什么是Form?
OFBiz中的Form不像我们理解的那样,必须有好几行好几列![](https://img-my.csdn.net/uploads/201304/10/1365559878_9116.png)
这个是form
Form的使用
- form不可以直接访问及使用,必须要include进screen中才能使用
- 定义:我们一般把form的定义单独写在一个xml文件中,放在widgets这个目录下,如LearningForms.xml,一个简单的定义如下:
<form name="FirstForm" type="single" target="processFirstForm"> <field name="firstName"><text/></field> <field name="lastName"><text/></field> <field name="submit"><submit/></field> </form>
其中,
<form name="FirstForm" type="single" target="processFirstForm">
定义了form的名字,类型,以及如果form中的按钮(如submit)按下以后会发送什么样的request
<field name="firstName"><text/></field> <field name="lastName"><text/></field> <field name="submit"><submit/></field>
field选项定义了这个form有多少个属性,后面的<text><submit>则是说明这个属性到底是什么类型的,需要输入呢?还是是按钮可以按
OFBiz有个很贴心的地方,他会自动为我们的各个属性加入对应的标签,如图
我并没有在form添加label,但它自动生成了label,每个label的内容正是field标签中的name,但是又有一点变化,它使用驼峰原则,并且将单词分开,首字母大写。
当然,如果你想自己指定显示的名称,加上title属性即可
- 使用
在screen中添加form的方法很简单,使用<include form>即可
<screen name="OneFormScreen"> <section> <widgets> <decorator-screen name="xhtml-decorator"> <decorator-section name="title"> <label text="A Screen with just 1 form."/> </decorator-section> <decorator-section name="body"> <include-form name="FirstForm" location="component://learning/widget/learning/LearningForms.xml"/> </decorator-section> </decorator-screen> </widgets> </section> </screen>
Form的事件处理
<form name="FirstForm" type="single" target="processFirstForm">
<field name="firstName"><text/></field>
<field name="lastName"><text/></field>
<field name="submit"><submit/></field>
</form>
当form的submit按钮按下时候,会触发一个request,这个request的名字是有规律的:一般来说是process+list的名字(见name标签)。当然,你也可以设置target这个标签,这个标签规定了按下了form的按钮后会触发什么样的request
既然发送了request,我们肯定要在controller.xml中写相应的<request-map>来进行监听。
一般来说,按下按钮以后常常是需要对表中的数据进行一定处理(正如同form定义中的target这个标签,我们需要process form),而不是直接返回一个view。我们常常会定一个event来处理这些处理事件,所以<request-map>的完整版这样写
<request-map uri="processFirstForm">
<event type="java" path="org.ofbiz.learning.learning.LearningEvents" invoke="processFirstForm"/>
<response name="success" type="view" value="OneFormScreen"/>
</request-map>
下面来解读event这一行:
type - 说明这个event是什么类型的,常用的有java的,还有minilang的
path - 说明event文件在哪里,对于java来说,就是在那个包中
invoke - 调用这个event文件中的具体哪一个方法
我的简单理解,event就相当于对java类中一个方法的调用。
那么,这个java文件到底是什么样的呢?
package org.ofbiz.learning.learning;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.ofbiz.base.util.UtilHttp;
public class LearningEvents {
public static String processFirstForm(HttpServletRequest request,
HttpServletResponse response){
String firstName = request.getParameter("firstName");
String lastName = request.getParameter("lastName");
request.setAttribute("combined", firstName + " " + lastName);
request.setAttribute("allParams", UtilHttp.getParameterMap(request));
request.setAttribute("submit", "Submitted");
return "success";
}
}
需要注意的是,被调用的方法,一定要是static的,这样就不必要实例化一个类了
那么,这个方法是如何知道用户输入了什么?又如何输出计算处理后的结果呢?
很好理解,使用request.getParameter可以得到用户输入的信息。
request.getParameter("firstName")对应<field name="firstName"><text/></field>的信息
request.getParameter("lastName")对应<field name="lastName"><text/></field>的信息
同样,使用setAttribute()方法,我们可以把event中计算的结果返回给screen使用,我们在screen中,可以这样得到event中处理的结果:
<container><label text="firstName: ${parameters.firstName}"/>
</container>
<container><label text="lastName: ${parameters.lastName}"/>
</container>
<container><label text="combined: ${parameters.combined}"/>
</container>
<container><label text="submit: ${parameters.submit}"/></container>
<container><label text="All the parameters we received:"/>
</container>
<container><label text="${parameters.allParams}"/></container>
Form的类型及详解
single类型
Single类型的Form最简单,只能有一个Record,只有一组数据<form name="FirstForm" type="single" target="processFirstForm1">
<field name="firstName"><text/></field>
<field name="lastName"><text/></field>
<field name="submit"><submit/></field>
</form>
![](https://img-my.csdn.net/uploads/201304/10/1365559878_9116.png)
list类型
List类型的Form就是我们日常用的form,有表头,可以有很多行
<form name="ListForm" type="list" list-name="listOfRecords"
target="processListForm" separate-columns="true">
<field name="firstName"><text/></field>
<field name="lastName"><text/></field>
<field name="submit"><submit/></field>
</form>
![](https://img-my.csdn.net/uploads/201304/10/1365559885_3009.png)
从上图可以看出,list类型的form实际上是由很多个single类型的form组成的。
看表的定义,与single相比,多了list-name和separate-columns这两个属性。
我们先看separate-columns这个属性,为true的时候效果如上图,如果为false呢?
可以看到三个属性名全部连在一起放在一格中了
至于list-name这个属性,需要结合screen来看。由于form的定义中只说明了有几个属性(几列),具体有多少行多少个record则是在screen中设定的。代码如下:
<screen name="ListFormScreen">
<section>
<actions>
<set field="row1.firstName" value="First1"/>
<set field="row1.lastName" value="Last1"/>
<set field="row2.firstName" value="First2"/>
<set field="row2.lastName" value="Last2"/>
<set field="row3.firstName" value="First3"/>
<set field="row3.lastName" value="Last3"/>
<set field="listOfRecords[]" from-field="row1"/>
<set field="listOfRecords[]" from-field="row2"/>
<set field="listOfRecords[]" from-field="row3"/>
</actions>
<widgets>
<decorator-screen name="xhtml-decorator">
<decorator-section name="title">
<label text="A Screen with a list of forms."/>
</decorator-section>
<decorator-section name="body">
<include-form name="ListForm"
location="component://learning/widget/learning/LearningForms.xml"/>
<include-screen name="ShowProcessing"/>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
很明显,我们在action中设定了有多少个record。我们注意到有这样的几句:
<set field="listOfRecords[]" from-field="row1"/>
<set field="listOfRecords[]" from-field="row2"/>
<set field="listOfRecords[]" from-field="row3"/>
如果我将form定义中的list-name改为listOfRecords1,重新访问
![](https://img-my.csdn.net/uploads/201304/10/1365559893_5546.png)
可以看到,所有内容都无法显示了
如果将row2的field改为listOfRecords1,则
所以,我认为,list-name定义了表中一个完整的行的类型名称,这个名称是在screen中使用的。只有将field设定为${list-name}+[]的形式,他才能特指表中的一行。
Multi类型
代码如下: <form name="MultiForm" type="multi" list-name="listOfRecords"
target="processMultiForm" separate-columns="true">
<field name="firstName"><text/></field>
<field name="lastName"><text/></field>
<field name="_rowSubmit" title="Select"><check/></field>
<field name="submit"><submit/></field>
</form>
效果如下:
![](https://img-my.csdn.net/uploads/201304/10/1365559906_7125.png)
可以发现,multi类型的form的定义和list是很像的,只有type不同而已。
用途上的区别如下:
It is often useful to edit a whole list of records in one go, and then click a single Submit button to update them all. The single and the list type form widgets cannot allow this; they can only allow the update of a single record at every click of a Submit button.
简单来说,就是一次可以提交多份,而不像list需要一个一个地提交。
Form中field元素
输入框
效果:![](https://img-my.csdn.net/uploads/201304/10/1365559911_5094.png)
定义:<text/>
<field name="firstName"><text/></field>
获取内容的方法:
String firstName = request.getParameter("firstName");
提交按钮
效果:![](https://img-my.csdn.net/uploads/201304/10/1365559916_4116.png)
定义:<submit/>
<field name="submit"><submit/></field>
check box
效果![](https://img-my.csdn.net/uploads/201304/10/1365559921_9669.png)
定义:<check/>
<field name="_rowSubmit" title="Select"><check/></field>
如果将name改动一下,改成其他的
![](https://img-my.csdn.net/uploads/201304/10/1365559925_2331.png)
就会发现表头的那个全选没有了
Form中的其他元素
<alt-target><row-actions>