目录

1、Form页面的Html代码

2、前端JS实现将DataGrid中的明细数据打包提交

3、后台接收提交数据的代码

4、Application业务中的保存方法


前言

很多使用DaleCloud(原NFine)框架的同学一直在问,如何实现一对多的主从表业务数据提交。起始这是大部分做业务系统人的常见问题。比如我们的采购订单,入库单,出库单,等常见业务单据都存在主表+明细表的业务逻辑。

那么如何实现一个页面完成主表和明细表的增删改查呢?

给大家举个例子:

前端样式

使用这套框架的都知道Form页面的表单如何提交,其实就是在Form页增加一个easyUI的datagrid组件,然后通过datagrid的editor功能实现明细数据的增删改功能。然后再提交的时候把datagrid里的数据打包和Form表单一起提交到后台,后台取出数据转换成明细表的实体数组即可。

1、Form页面的Html代码

form页面使用easyUI的easyui-layout 将页面分为上下两部分。上部分north为主表Form表单。下部分center为明细表的Datagrid;

关于Datagrid的创建以及实现列可编辑的方法见http://www.jeasyui.net/plugins/183.html

<div class="easyui-layout" data-options="fit:true"><div data-options="region:'north',collapsible:false" style="height:35%;padding-top:5px;"><form id="form1" method="post"><table class="form"><tr><th class="formTitle">项目名称</th><td class="formValue" colspan="3"><input id="T_ProjectName" name="T_ProjectName" type="text" class="easyui-textbox " data-options="required:true,prompt:'必填,无项目请填客户名称或用途'" style="width:100%" /></td></tr><tr><th class="formTitle">项目编号</th><td class="formValue"><input id="T_ProjectNo" name="T_ProjectNo" type="text" class="easyui-textbox " data-options="required:true,prompt:'必填,无项目请填当前日期,如:20190101'" style="width:100%" /></td><th class="formTitle">单据类别</th><td class="formValue"><select id="T_Level" name="T_Level" class="easyui-combobox" style="width:100%"><option value="常规件" selected>常规件</option><option value="急件">急件</option></select></td></tr><tr><th class="formTitle">项目审批人</th><td class="formValue"><input id="T_ApproverId" name="T_ApproverId" type="text" class="easyui-textbox " data-options="required:true,prompt:'如项目组长,部门领导,总经理等'" style="width:100%" /></td><th class="formTitle">采购确认人</th><td class="formValue"><input id="T_ReceiverId" name="T_ReceiverId" type="text" class="easyui-textbox " data-options="prompt:'默认请选择刘召英'" style="width:100%" /></td></tr><tr><th class="formTitle" valign="top" style="padding-top: 5px;">备注说明</th><td class="formValue" colspan="3"><textarea id="T_Remark" name="T_Remark" class="easyui-textbox " data-options="prompt:'用途/技术要求等'" style="width:100%;height: 80px;"></textarea></td></tr></table></form></div><div data-options="region:'center'"><div id="toolbar" style="padding:2px 5px;"><div class="dcui-btn-area"><a href="javascript:void()" id="NF-add" authorize="yes" onclick="append()" class="dcui-btn dcui-btn-green"><i class="fa fa-plus"></i>新增</a><a href="javascript:void()" id="NF-removeit" authorize="yes" onclick="removeit()" class="dcui-btn dcui-btn-red"><i class="fa fa-trash"></i>删除</a><a href="javascript:void()" id="NF-save" authorize="yes" onclick="accept()" class="dcui-btn dcui-btn-blue"><i class="fa fa-save"></i>确认</a></div><script>$('#tb2').authorizeButton()</script></div><table id="dg_detail" title="订单明细" class="easyui-datagrid" style="width:100%;min-height:300px; padding:5px;"><thead><tr><th data-options="field:'T_ItemName',width:140,align:'right',editor:'textbox'">物料名称</th><th data-options="field:'T_Mode',width:140,align:'right',editor:'textbox'">规格型号</th><th data-options="field:'T_TechParam',width:120,align:'right',editor:'textbox'">技术参数</th><th data-options="field:'T_Manufacturer',width:120,align:'right',editor:'textbox'">厂家</th><th data-options="field:'T_Quantity',width:60,align:'right',editor:{type:'numberbox',options:{precision:1}}">数量</th><th data-options="field:'T_Price',width:60,align:'right',editor:{type:'numberbox',options:{precision:1}}">价格</th><th data-options="field:'T_IsStock',width:60,align:'center',editor:{type:'checkbox',options:{on:'有',off:'无'}}">库存</th><th data-options="field:'T_DeliveryDate',width:100,align:'center',editor:{type:'datebox'}">交货日期</th><th data-options="field:'T_ItemCode',width:100,align:'right',editor:'textbox'">存货编号</th><th data-options="field:'T_Remark',width:140,align:'right',editor:'textbox'">备注</th></tr></thead></table><div class="form-button" id="wizard-actions"><a id="btn_save" class="btn btn-default btn-prev" onclick="submitForm()">保存</a><a id="btn_sure" class="btn btn-primary btn-prev" onclick="submitConfirm()">保存并发布</a><a id="btn_close" class="btn btn-warning" onclick="submitClose()">关闭</a></div></div>
</div>

2、前端JS实现将DataGrid中的明细数据打包提交

这里面有三个注意的:一个是对Datagrid编辑的操作和验证。一个是获取所有行的数据。另一个数form表单提交的时候附加明细;

 var keyValue = $.request("keyValue");$(function () {initControl();if (!!keyValue) {$.ajax({url: "/ProjectManage/InterPurchase/GetFormJson",data: { keyValue: keyValue },dataType: "json",async: false,success: function (data) {$('#form1').form('load', data.main);}});var queryJson = {keyValue: keyValue}$('#dg_detail').datagrid('load', queryJson);}});//初始化function initControl() {$.ajax({url: "/BizData/GetSysUserJson",type: "get",dataType: "json",async: false,success: function (data) {$("#T_ApproverId").combogrid({data: data,multiple: true,panelWidth: 220,idField: 'F_Id',textField: 'F_RealName',columns: [[{ field: 'F_RealName', title: '名字', width: 100 },{ field: 'F_DepartmentId', title: '部门', width: 100 }]],filter: function (q, row) {var opts = $(this).combogrid('options');return row[opts.textField].indexOf(q) >= 0;}});$("#T_ReceiverId").combogrid({data: data,multiple: true,panelWidth: 220,idField: 'F_Id',textField: 'F_RealName',value: '172461185220895901',columns: [[{ field: 'F_RealName', title: '名字', width: 100 },{ field: 'F_DepartmentId', title: '部门', width: 100 }]],filter: function (q, row) {var opts = $(this).combogrid('options');return row[opts.textField].indexOf(q) >= 0;}});}});$('#dg_detail').datagrid({url: "/ProjectManage/InterPurchase/GetDetailGridJson",toolbar: '#toolbar',hideColumn: "T_Id",method: 'get',autoRowHeight: false,nowrap: true,singleSelect: true,queryParams: {keyword: "",keyValue: keyValue},onClickRow: onClickRow});}//审核表单function submitConfirm() {$.modalConfirm("注:是否确认同意审核采购申请?", function (r) {if (r) {if (endEditing()) {$('#dg_detail').datagrid('acceptChanges');} else {$.modalMsg("请检查订单明细", "warning");return;}$.submitEasyUIForm({form: "form1",url: "/ProjectManage/InterPurchase/SubmitForm?isConfirm=true&keyValue=" + keyValue,param: { details: getrows() },success: function () {$.currentWindow().$('#dg_detail').datagrid('load');}})}});}//提交Form表单function submitForm() {// 先验证明细是否完成编辑if (endEditing()) {$('#dg_detail').datagrid('acceptChanges');} else {$.modalMsg("请检查订单明细", "warning");return;}$.submitEasyUIForm({form: "form1",url: "/ProjectManage/InterPurchase/SubmitForm?isConfirm=false&keyValue=" + keyValue,param: { details: getrows() },//将fdatagrid数据打包提交success: function () {$.currentWindow().$('#dg_detail').datagrid('load');}})}//定义当前可编辑行的indexvar editIndex = undefined;// 结束当前编辑行的编辑操作function endEditing() {if (editIndex == undefined) { return true }if ($('#dg_detail').datagrid('validateRow', editIndex)) {$('#dg_detail').datagrid('endEdit', editIndex);editIndex = undefined;return true;} else {return false;}}// 单击行实现其他行取消编辑,当前行开始编辑function onClickRow(index) {if (editIndex != index) {if (endEditing()) {$('#dg_detail').datagrid('selectRow', index).datagrid('beginEdit', index);editIndex = index;} else {$('#dg_detail').datagrid('selectRow', editIndex);}}}// 添加新的一行,并且设置库存数据初始值为1function append() {if (endEditing()) {$('#dg_detail').datagrid('appendRow', { T_Quantity: 1 });editIndex = $('#dg_detail').datagrid('getRows').length - 1;$('#dg_detail').datagrid('selectRow', editIndex).datagrid('beginEdit', editIndex);}}// 移除行(移除前先取消编辑)function removeit() {if (editIndex == undefined) { return }$('#dg_detail').datagrid('cancelEdit', editIndex).datagrid('deleteRow', editIndex);editIndex = undefined;}// 结束编辑并将datagrid设置为接收数据变化,这样才能正确获取到行的数据function accept() {if (endEditing()) {$('#dg_detail').datagrid('acceptChanges');}}//获取datagrid的所有行数据,并转为json字符串格式function getrows() {var rows = $('#dg_detail').datagrid('getRows');var entities = '';for(i = 0;i < rows.length;i++){entities = entities  + JSON.stringify(rows[i]);}return JSON.stringify(rows);}

3、后台接收提交数据的代码

我们常规的Form表单提交方法SubmitForm方法的参数主要是主键和Mode实体。如果有明细数据,那么需要添加一个参数,我命名为string类型的details。然后新建一个明细表实体的数组。通过.ToList()方法即可将json字符串转为实体数组。然后提交

        [HttpPost][ValidateAntiForgeryToken]public ActionResult SubmitForm(PurchaseMainEntity uEntity,string details, string keyValue,bool isConfirm){try{List<PurchaseDetailsEntity> detail=new List<PurchaseDetailsEntity>();detail = details.ToList<PurchaseDetailsEntity>();app.SubmitForm(uEntity, detail, keyValue, isConfirm);return Success("操作成功。");}catch(Exception ex){return Error(ex.Message);}}

4、Application业务中的保存方法

先保存主表,然后循环保存明细表;我这里没有做保存失败的回滚。建议大家做好这个验证;

/// <summary>/// 保存/// </summary>/// <param name="mEntity"></param>/// <param name="details"></param>/// <param name="keyValue"></param>/// <param name="isConfirm">是否确认</param>public void SubmitForm(PurchaseMainEntity mEntity, List<PurchaseDetailsEntity> details, string keyValue, bool isConfirm){if(details==null || details.Count == 0){throw new Exception("请添加明细");}mEntity.T_Approver = CommonApp.GetUserName(mEntity.T_ApproverId);mEntity.T_Receiver = CommonApp.GetUserName(mEntity.T_ReceiverId);if (!string.IsNullOrEmpty(keyValue)){mEntity.Modify(keyValue);mEntity.T_Originator = CommonApp.GetUserName(mEntity.T_CreatorUserId);service.Update(mEntity);}else{mEntity.Create();mEntity.T_OriginatorId = mEntity.T_CreatorUserId;mEntity.T_Originator = CommonApp.GetUserName(mEntity.T_CreatorUserId);mEntity.T_OrderNo = Utils.GetOrderNumber();service.Insert(mEntity);}if (!string.IsNullOrEmpty(mEntity.T_Id)){detailservice.Delete(t => t.T_PurchaseId == mEntity.T_Id);}// 明细处理foreach (PurchaseDetailsEntity detail in details){detail.T_Id = CommonUtils.GuId();detail.T_PurchaseId = mEntity.T_Id;detail.T_OrderNo = mEntity.T_OrderNo;detailservice.Insert(detail);}if (isConfirm){InterPurchaseWorkMsg.OrderNoticeiMsgtoApprover(mEntity);}}

DaleCloud(原NFine)介绍:使用easyui实现主从表提交(单据业务)相关推荐

  1. Winform界面中主从表编辑界面的快速处理

    在Winform开发中,我们往往除了常规的单表信息录入外,有时候设计到多个主从表的数据显示.编辑等界面,单表的信息一般就是控件和对象实体一一对应,然后调用API保存即可,主从表就需要另外特殊处理,本随 ...

  2. iOS:Masonry 英文原档介绍

    Masonry 英文原档介绍: Masonry is still actively maintained, we are committed to fixing bugs and merging go ...

  3. 在GridControl表格控件中实现多层级主从表数据的展示

    在一些应用场景中,我们需要实现多层级的数据表格显示,如常规的二级主从表数据展示,甚至也有多个层级展示的需求,那么我们如何通过DevExpress的GridControl控表格件实现这种业务需求呢?本篇 ...

  4. oracle主从关系表查询,Oracle 主从表联合查询解决方法

    Oracle 主从表联合查询 表A id   type   name 1    E      AA 2    F 表B id   Aid    name 1    2      BB 2    2   ...

  5. GZFramwork数据库层《四》单据主从表增删改查

    同GZFramwork数据库层<三>普通主从表增删改查 不同之处在于:实例 修改为: 直接上效果: 项目源码下载地址:https://github.com/GarsonZhang/GZFr ...

  6. 主从表 ajax,DWZ主从表结构 · Issue #72 · OtakuFly/dwz · GitHub

    使用DWZ主从表结构,从表读取数据集显示,用于表单修�� �功能 ID所属专业工作量项目单位数量操作 查找带回 查找带回 删除 通过增加明细按钮,可以增加表格行,表格行最后的删除按�� �,可以删除新 ...

  7. devexpress 主从表中从主、从表行列值的获得

    一,主从表的设置 代码             DataTable dt = pb.GetItemInfoList(Port).Copy(); //返回一个TABLE             dt.T ...

  8. JSON序列——主从表查询

    JSON序列--主从表查询 客户端代码: procedure TForm1.Button4Click(Sender: TObject); // 主从表 查询 beginvar url: TynUrl ...

  9. WPF DataGrid 主从表 数据绑定方式

    昨天在网上搜了一下午没有看到一个关于WPF DataGrid主从表数据绑定的示例,但是我坚信这个简单的功能肯定是支持的,经研究问题解决. 现把相关方法共享下,给现在还在郁闷的兄弟们一点参考.重点在于定 ...

最新文章

  1. 半导体并购停不下来 ADI拟148亿美元收购Linear
  2. python 字符串分割和拼接_python分割和拼接字符串
  3. Ubuntu 12.04 64bit 安装编译GCC 4.1.2 绝对原创
  4. mysql5.7.14安装版教程_MySQL5.7.14下载安装图文教程及MySQL数据库语句入门大全
  5. 扫地机器人滤网顺序_1分钟小课堂:扫地机器人滤网多久换一次?
  6. 用R读取Excel的新方法
  7. PHP多重身份认证,浅谈php用户身份认证
  8. DM365的UBL源码分析(二)
  9. 数据密集型系统设计pdf下载
  10. Python:混合动力汽车能量管理_动态规划简版(1/2)
  11. IV WOE 评分卡 分箱
  12. antv g2字体阴影_antv-g2学习手册-中
  13. 莫国防病毒(win32.mgf)源代码
  14. 手机java update_手机里的java菜单老是自动更新为什么啊
  15. 【微信】微信,是一个生活方式
  16. 计算机睡眠状态如何恢复,显示器进入睡眠状态怎么解决
  17. 二、生理信号处理 ——1.心电信号(含Matlab代码及数据)
  18. 左旋右旋问题一次搞定!!!
  19. Boost学习之语法解析器--Spirit
  20. 【运维面试】面试官:你们公司的docker主要用来做啥?

热门文章

  1. Java创建多级文件夹
  2. Ubuntu换Kali源
  3. 数学建模:评价性模型学习——灰色关联分析法(GRA模型)
  4. RSSI CSQ 转换函数
  5. 使用LED灯和Arduino开发板制作一个智能马克杯
  6. JAVA基础 多线程技术学习笔记(V1.0)
  7. AI作画—山海经异兽
  8. 基于ALS的音乐分析及离线推荐系统的设计与实现报告
  9. 微信小程序源代码_模仿共享单车ofo
  10. BYSBZ 1696(建牛舍)