Web DbForms (续一)
(说明:由于本人水平有限,所以翻译错误在所难免。为了不给读者造成错误的概念,这里采用了中英文对照方式)
A Simple Example
一个简单例子
Description: This JSP view (service.jsp) enables the user(s) to administer the services the agency provides to its customers. The user (an employee of the agency or call center agent) should get a list of all the existing services, along with textfields and buttons to update and delete data. Finally, an empty input mask for inserting new services is needed.
描述:此JSP视图(service.jsp)允许用户管理代理商提供给客户的服务。用户(代理商的一个雇员或者呼叫中心的代表)会得到一个所有存在的服务的列表,连同文本输入框和按钮一起来更新和删除数据。最后,需要一个空的输入界面来增加新的服务。
Listing 1. -- service.jsp
<%-- import DbForms tag library --%>
<%@ taglib uri="/WEB-INF/taglib.tld" prefix="db" %>
<html>
<head>
<db:base/>
</head>
<body>
<db:errors/> <%-- show eventually occured errors --%>
<db:dbform tableName="service" maxRows="*" followUp="/service.jsp">
<%-- the header gets rendered one time --%>
<db:header>
<db:gotoButton caption="Menu" destination="/menu.jsp" />
<h1>Services we provide</h1>
<center><h3>Our existing services</h3></center>
<table border="5" width="60%" align="CENTER">
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Actions</th>
</tr>
</db:header>
<%-- the body gets rendered for each data row in the query
it contains textfields and action buttons for manipulating data --%>
<db:body>
<tr>
<td><db:textField fieldName="id" size="5"/><;/td>
<td><db:textField fieldName="name" size="20" maxlength="30"/></td>
<td><db:textField fieldName="description" size="24" maxlength="255"/></td>
<td>
<db:updateButton caption="Update"/>
<db:deleteButton caption="Delete"/>
</td>
</tr>
</db:body>
<%-- the footer gets rendered 1 time
it contains a textfields for entering new datasets --%>
<db:footer>
</table>
<center><h3>Enter new service:</h3></center>
<table align="center" border="3">
<tr>
<td>Id</td>
<td><db:textField size="5" fieldName="id"/></td>
</tr>
<tr>
<td>Name</td>
<td><db:textField size="20" maxlength="30" fieldName="name"/></td>
</tr>
<tr>
<td>Description</td>
<td><db:textArea rows="4" cols="20" wrap="virtual" fieldName="description"/></td>
<tr>
</table>
<br><center><db:insertButton caption="Insert new service!"/></center>
</db:footer>
</db:dbform>
</body>
</html>
Remarks
备注
We have set maxRows to "*" which has the effect that all rows will be shown at once. If there exist hundreds of services, we would like to set maxRows to "10," "20," or another limited number, and we would instantiate navigation buttons for scrolling between the pages. We will use that pattern later.
我们已经把maxRows的值设置成“*”,这样一次会显示所有的行。如果有很多服务,我们可以把maxRows的值设成“10”,“20”,或者其他有限的数字。我们可以和通过导航按钮在页面间来回翻动。后面会用到这个图。
The errors tag shows a list of errors, if any occurred (i.e. duplicate key error, etc.).
如果发生了错误(例如,重复键错误等等),错误标签会显示出错误列表。
The updateButton and deleteButton tags are placed in the body and therefore rendered for each row.
表体中插入的updateButton和deleteButton标签,在每行都会显示出来。
The result is shown in Figure 3:
结果如图3所示
Figure 3. Managing services (service.jsp)
An Example of Nested Forms
一个嵌套表单的例子
The following page (customer_order.jsp) gives you the functionality to manage the incoming orders of a customer. You are able to edit both orders of a customer and the customer data itself. Furthermore, you do not need to struggle with plain service IDs, but will be able to conveniently select the services from a select box by name.
下面的页面(customer_order.jsp)让你能管理收到的客户订单。你既可以编辑客户订单,也可以编辑客户数据。此外,你不用对单调的服务ID苦恼,相反,可以方便的在选择列表中用姓名来选择服务。
Figure 4. Underlying data for customer_order.jsp
Listing 2. customer_order.jsp
<%-- import DbForms tag library --%>
<%@ taglib uri="/WEB-INF/dbforms.tld" prefix="db" %>
<html>
<head>
<db:base/>
</head>
<body>
<db:errors/> <%-- show eventually occured errors --%>
<%-- the root form --%>
<db:dbform tableName="customer" maxRows="1" followUp="/customer_orders.jsp"
autoUpdate="false">
<db:header>
<db:gotoButton caption="Menu" destination="/menu.jsp" />
<h1>Customer</h1>
</db:header>
<db:body> <%-- the body shows the data of the current customer --%>
<table align="center">
<tr>
<td>Id </td>
<td><db:textField fieldName="id" size="4"/></td>
</tr>
<tr>
<td>First Name</td>
<td><db:textField fieldName="firstname" size="18"/></td>
</tr>
<tr>
<td>Last Name</td>
<td><db:textField fieldName="lastname" size="18"/></td>
</tr>
<tr>
<td>Address:</td>
<td><db:textField fieldName="address" size="25" /></td>
</tr>
<tr>
<td>Postal code/City</td>
<td><db:textField fieldName="pcode" size="6"/> -
<db:textField fieldName="city" size="16"/> </td>
</tr>
</table>
<br>
<%-- table embedding the subform --%>
<table align="center" border="1">
<tr>
<td>
<center><p><b>Orders</b></p></center>
<%-- this is the begin of the subform:
the subform renders all the services the current customer has ordered --%>
<db:dbform tableName="orders" maxRows="3" parentField="id" childField="customer_id"
followUp="/customer_orders.jsp" autoUpdate="false">
<db:header>
<%-- code for showing existing orders of services for that customer --%>
<table>
<tr>
<td width="40"></td>
<td>service</td>
<td>orderdate</td>
</tr>
</db:header>
<db:body allowNew="false">
<tr>
<td width="40"><db:associatedRadio name="radio_order" /></td>
<td>
<db:select fieldName="service_id"> <%-- this allows the --%>
<db:tableData <%-- users of the application to --%>
name = "our_services" <%-- select services conveniently --%>
foreignTable = "service" <%-- from a select-box --%>
visibleFields = "name"
storeField = "id"
/>
</db:select>
</td>
<td><db:dateField fieldName="orderdate" size="14"/></td>
</tr>
</db:body>
<db:footer>
<tr>
<td width="40"></td>
<td><db:updateButton caption="Update Order" associatedRadio="radio_order"/></td>
<td><db:deleteButton caption="Delete Order" associatedRadio="radio_order"/></td>
</tr>
</table>
<%-- code for entering new orders of services --%>
<br><hr>
<table>
<tr>
<td>service</td>
<td>date</td>
<td></td>
</tr>
<tr>
<td>
<db:select fieldName="service_id">
<db:tableData
name = "our_services"
foreignTable = "service"
visibleFields = "name"
storeField = "id"
/>
</db:select>
</td>
<td><db:dateField fieldName="orderdate" size="10" /></td>
<td><db:insertButton caption="insert order" /></td>
</tr>
</table>
<center> <%-- navigating in the subform (in the list of orders of a customer --%>
<db:navFirstButton caption="<< First" />
<db:navPrevButton caption="< Previous" />
<db:navNextButton caption="Next >" />
<db:navLastButton caption="Last >>" />
</center>
</db:footer>
</db:dbform>
<%-- subform end --%>
</td>
</tr>
</table>
<%-- end of table embedding the subform --%>
<br><center>
<db:insertButton caption="Store this new Customer!" /> <%-- action buttons for --%>
<db:updateButton caption="Update Customer" /> <%-- editing data of --%>
<db:deleteButton caption="Delete Customer" /> <%-- customers --%>
</center>
</db:body>
<db:footer>
<br><center>
<db:navFirstButton caption="<< First" /> <%-- navigating in the --%>
<db:navPrevButton caption="< Previous" /> <%-- list of customers --%>
<db:navNextButton caption="Next >" />
<db:navLastButton caption="Last >>" />
<db:navNewButton caption"*"/>
</center>
</db:footer>
</db:dbform>
</body>
</html>
Remarks
备注
With this page, we have demonstrated another couple of major features of DbForms:
在本页,我们已经讲述了DbForms的另外一些主要特征:
Nested Forms: The structure of this page is similar to the structure shown in Figure 2: a main form has a sub-form inside its body. The sub-form is linked to its parent by the equality of data fields defined in the child form's parentField and childField attributes. (If there is more than one field defining this mapping, a list of fields may be provided, with each field separated from the other by characters like "," or ";" or "~".)
嵌套表单:本页的结构和图2中的结构很相似:一个主表单表体中有一个子表单。子表单的parentField和childField属性中定义的数据域的共性使子表单和父表单关联起来。(如果有多个域定义了这个映射,就会有一个域的列表,每个域间用“,”或“;”或“~”隔开。)
Navigation Buttons: Because only one customer is visible at a time, the user needs a way to navigate between records. This functionality is provided by navFirstButton, navLastButton, navPrevButton, navNextButton elements.
导航按钮:由于一次只有一个客户可见,用户需要一个方法在记录间移动。navFirstButton,navLastButton,navPrevButton,navNextButton元素则提供了此功能。
Insert Button: the navNewButton element navigates the user to an empty form to enter new data.
插入按钮:navNewButton元素指导用户进入一个空表单来输入新数据。
select Tag: In addition to textField and textArea tags, more complex elements like select, radio, and checkbox can be used for data visualization and manipulation. I have chosen a select tag to select the type of service a customer orders.
选择标签:除了textField和textArea标签,更多复杂的元素例如选择列表,单选和多选被用来显示和操作数据。我选择了一个选择标签来选择客户订单的服务类型。
External data fetched by a tableData tag: This tag provides external data to radio, checkbox, or select tags. It may be used for cross-references to other tables. In our case, we initalized the select box with external data from the table "service." Be aware that you have to distinguish between the field(s) to be shown to the user and those to be stored in the associated field in the table. In our case, we have shown the field service.name and stored the value service.id in the associated field orders.service_id! The name our_services was defined to enable internal caching of data, which increases performance.
外部数据来自一个tableData标签:此标签用单选,多选和选择列表来显示外部数据。这可以用于和其他表的交叉引用。在我们的案例中,我们用“service”表的外部数据来初始化选择列表。注意,你必须区分显示给用户的字段和那些在存于关联表中字段的区别。此案例中,我们已经看到了service.name字段,并且把service.id的值保存于相关字段orders.service_id中!为了内部数据缓冲以提高性能,我们定义了our_services字段名。
Using associatedRadio elements to mark rows of data for certain actions (in our case we mark "orders" for the actions "update" and "delete") saves a lot of space and makes the interface clearer. If we had to draw a button for all possible actions for each row of data, the page would not look very friendly.
使用associatedRadio元素来为某些动作(在此案例中,我们为动作“update”和“delete”标记“orders”)标记数据不但节省了很多空间,还使接口清晰。如果我们不得不为每行数据的所有可能动作都设一个按钮,那么这个页面看起来可能就不那么友好了。
Figure 5. Managing orders and customers with one single page (customer_order.jsp)
(未完待续)