业务表单是业务数据录入的主要界面,在系统中必不可少,表单内的填写项与数据库表的字段相对应,保存表单时,把表单项输入的内容保存到对应的数据库业务表中。因此,同一个业务表单一般会分为新增用的、修改用的、显示用的三个类型界面。但在实际应用中,做三个同样的表单不仅费时费力,还不好维护,所以应该要做到三种类型的表单共用一个业务表单,这样将大大减少开发量。
下面就以一个新闻表单做为例子进行简单说明
新闻表结构如下图,其中NEWS_ID字段为主键,数字型。
1)在定义好这个表结构后,就可以用hibernate来生成这个表的实体类了,如下图
2)编写表单,如以下代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/WEB-INF/bl_tag.tld" prefix="BL"%>
<html>
<head>
<BL:RootBase id="blRoot" form_id="xmglForm" ></BL:RootBase>
<title></title>
<script>
//按钮单击
function onBtnClick(_id){
if(_id=='rcBaseToolbar0'){
var win = top.bl_global.getParentFrame(top,'fb');
bl_global.form_submit('SaveNews');
win.bl_global.grid_reload(win.grid_NewsPage);
}
if(_id=='rcBaseToolbar4'){
top.bl_global.pop_window_x_close('fb');
}
}
</script>
</head>
<body id="body_lay" >
<BL:DataSet name="NewsForm" context="NewsForm" id="NewsForm"></BL:DataSet>
<form method="post" id="xmglForm" append="true" >
<table align="center" style="margin-top: 20px" id="projectTable" width="95%" class="bltable" border="0" cellspacing="0" >
<tbody>
<tr>
<td class="bg" width="90px" height="24">
新闻标题
</td>
<td colspan="3">
<BL:TextBox valid_auth="[{0:[notempty,'请输入新闻标题!']}]" id="NEWS_TITLE" key="NEWS_TITLE" context="NewsForm" type="text" ></BL:TextBox>
</td>
</tr>
<tr>
<td class="bg" height="24">
发布人
</td>
<td >
<BL:TextBox style="width:120px" id="NEWS_FBR" key="NEWS_FBR" context="NewsForm" type="text" readonly="true" defaultvalue="u.name"></BL:TextBox>
</td>
<td class="bg" height="24">
发布时间
</td>
<td >
<BL:TextBox style="width:120px" id="NEWS_TIME" key="NEWS_TIME" context="NewsForm" type="text" readonly="true" defaultvalue="d.today"></BL:TextBox>
</td>
</tr>
<tr>
<td class="bg" height="24">
发布机构
</td>
<td >
<BL:TextBox style="width:120px" id="NEWS_ORG_NAME" key="NEWS_ORG_NAME" context="NewsForm" type="text" readonly="true" defaultvalue="u.orgname"></BL:TextBox>
</td>
<td class="bg" height="24">
状态
</td>
<td >
<BL:ComboBox id="NEWS_STATUS" key="NEWS_STATUS" text="[{'发布':'发布'},{'未发布':'未发布'}]" defaultvalue="发布"></BL:ComboBox>
</td>
</tr>
<tr>
<td class="bg" height="24">
新闻内容
</td>
<td colspan="3">
<BL:PPEditor id="NEWS_TEXT" context="NewsForm" init_editor_jslib="true" toolbar="FULL" ></BL:PPEditor>
</td>
</tr>
</tbody>
</table>
</form>
<BL:Layout patterns="1C" parentid="body_lay" id="RcCountLayout" init_layout_jslib="true" autoresize="true">
<BL:LayoutItem hidden_head="true" id="a1" parent_layout_id="RcCountLayout" object_id="xmglForm" title="" parent_layout_cell="a" inner_toolbar_id="rcBaseToolbar" inner_grid_id="">
<BL:ToolBar skins="dhx_skyblue" id="rcBaseToolbar" parentid="" οnclick="onBtnClick" layout_toolbar_id="rcBaseToolbar" grid_id="">
<BL:ToolBarItem index="0" valid_auth="{'VIEW_MODE':'R'}" name="保存" button_mode="btn" id="rcBaseToolbar" icon="save.png"></BL:ToolBarItem>
<BL:ToolBarItem index="3" name="" button_mode="sep" id="rcBaseToolbar"></BL:ToolBarItem>
<BL:ToolBarItem index="4" name="关闭" button_mode="btn" id="rcBaseToolbar" icon="close.png"></BL:ToolBarItem>
<BL:ToolBarItem index="5" name="" button_mode="sep" id="rcBaseToolbar"></BL:ToolBarItem>
</BL:ToolBar>
</BL:LayoutItem>
</BL:Layout>
<BL:TextBox context="NewsForm" id="NEWS_ID" key="NEWS_ID" type="hidden"></BL:TextBox>
<BL:TextBox context="NewsForm" id="NEWS_FBR_ID" key="NEWS_FBR_ID" type="hidden"></BL:TextBox>
<BL:TextBox context="NewsForm" id="NEWS_ORG_ID" key="NEWS_ORG_ID" type="hidden" defaultvalue="u.orgid"></BL:TextBox>
</html>
上面代码出现的都是表单的组件标签,平台约定,组件的名称对应表中的字段名称,如上边的
id="NEWS_TITLE" key="NEWS_TITLE"
就是对应表中的 NEWS_TITLE 字段,只要对应好了,在提交到后台时,平台会自动匹配并保存到数据库。
保存的代码就是上面的
<script>
//按钮单击
function onBtnClick(_id){
if(_id=='rcBaseToolbar0'){
var win = top.bl_global.getParentFrame(top,'fb');
bl_global.form_submit('SaveNews');
win.bl_global.grid_reload(win.grid_NewsPage);
}
if(_id=='rcBaseToolbar4'){
top.bl_global.pop_window_x_close('fb');
}
}
</script>
在提交完成后,还刷新了一下新闻列表。
运行效果如下图
3) 配置按钮点击保存操作名称为"SaveNews"的方法,前面教程有学过,配置如下
<Operate auth="保存新闻信息" class="" next_operate="" name="SaveNews" source="dhx" method="" esbmq="" auto="true" operate_mode="add" commit="true" operate_entity="LytNews" entity_primary="NEWS_ID">
<Return value="pass:error" msg="新闻信息保存成功!:新闻信息保存失败!" ></Return>
</Operate>
4) 在录入内容后,点击保存即可提交成功!如下图
5)编辑表单、查看表单都可以共用这一个表单。如下图
选中刚才的新闻记录后,选编辑,即可进行编辑状态的表单,新闻列表页面的按钮代码如下
function onBtnClick(_id,grid_object){
var w = $(window).width()-40;
var h = $(window).height()-20;
if(_id=='rcBaseToolbar0'){
top.bl_global.open_window('新增新闻','fb',w,h,'gxly/news/news_form.jsp' ,null,false,true,false,window);
}
if(_id=='rcBaseToolbar4'){
var dt_id = grid_object.getSelectedRowId();
if(dt_id!=''){
top.bl_global.open_window('编辑新闻','fb',w,h,'gxly/news/news_form.jsp?NEWS_ID='+dt_id ,null,false,true,false,window);
}
}
if(_id=='rcBaseToolbar6'){
var dt_id = grid_object.getSelectedRowId();
if(dt_id!=''){
bl_global.pop_dialog('请选择要删除的新闻记录','yesno',null,null,null,'bl_global.grid_delete(grid_NewsPage)','bl_global.dialog_close()');
}
}
if(_id=='rcBaseToolbar10'){
bl_global.open_query_window('查询','w_query',500,135,null,'squery',grid_object);
}
}
/**查看新闻信息*/
function onViewNews(_id){
var w = $(window).width()-40;
var h = $(window).height()-20;
top.bl_global.open_window('查看新闻','fb',w,h,'gxly/news/news_view.jsp?NEWS_ID='+_id+'&VIEW_MODE=PRINT_MODE' ,null,false,true,false,window);
}
可以看到,新增和编辑都是使用news_form.jsp,只不过编辑时,传了主键的值过去。如下图
可以看见变成编辑状态了,在保存时,平台自动会判断是否编辑状态,并决定调用insert或updata的平台内部实现方法。
而查看新闻也是一样,在点击记录行的标题名称时,除了传主键值过去以外,
还多了个参数
VIEW_MODE=PRINT_MODE
平台就可以知道,此表单以查看形式表现。
特点:
与传统的struts相比,免去配置action、actionForm等等这些配置,也不用什么spring注入什么类,把配置最小化,追求实用及简单。
也不用写什么insert table,updata 之类的SQL语句,平台自动完成,程序员只需要关心表单的制作。
表单还可以配置数据有效性的校验,如以上标题的代码
<BL:TextBox valid_auth="[{0:[notempty,'请输入新闻标题!']}]" id="NEWS_TITLE" key="NEWS_TITLE" context="NewsForm" type="text" ></BL:TextBox>
运行效果如下图
平台表单支持各种校验规则,如不能为空、数字、email、移动电话等等,并可以扩展,其实就是添加正则校验库而已。
基本一个新闻表单的演示就基本讲完了,主要也是配置,关键点就是表单的表单项命名要与数据库表的字段命名一致就行了。