在Bootstrap开发框架中使用dataTable直接录入表格行数据
在Winform开发的时候,我们很多时候可以利用表格控件来直接录入数据,不过在Web上较少看到,其实也可以利用dataTable对象处理直接录入表格行数据,这个可以提高数据的录入方便,特别是在一些简单业务的明细数据的时候,看起来会比弹出窗口录入方便一些,也高大上一点。本篇主要介绍在Bootstrap开发框架中使用dataTable直接录入表格行数据。
1、基于表格直接录入数据和Winform的界面回顾
在开始Web界面直接录入表格行数据前,我们先来看看Winform界面的处理情况,如我在流程管理里面,对于具有主从明细的报销业务表的数据处理,采用了下面的界面。
这种明细表单可以直接在表格控件Griview上进行新增、编辑处理。
而对于Web界面,如果我们要保持和这个布局类似的话,采用dataTable直接录入表格行数据也可以达到。
上面的界面处理明细数据的时候,可以直接使用新增记录,直接在录入框中输入数据,然后保存起来,保存后数据变为只读,如果需要修改,还可以单击编辑按钮进行修改。
而这些明细的数据,也仅仅存在JS的对象里面,还没有保存到后台数据库中,我们可以在最后保存(如上界面的确定按钮)处理中再获取全部添加的数据进行提交即可。
在这些数据提交之后,我们在查看界面里面可以可以Bootstrap Table插件来展示数据即可。
2、在Web上使用dataTable直接录入表格行数据的实现
上面的界面展示了在Web上使用dataTable直接录入表格行数据和数据展示,这里开始介绍它们的界面和实现代码。
界面部分主要是这个明细的处理。
界面视图的HTML代码如下所示。
<divclass="portlet light portlet-fit "> <divclass="portlet-title"> <divclass="caption"> <iclass="icon-settings font-red"></i> <spanclass="caption-subject font-red sbold uppercase">明细清单</span> </div> </div> <divclass="portlet-body"> <divclass="table-toolbar"> <divclass="row"> <divclass="col-md-6"> <divclass="btn-group"> <buttonid="detail_editable_1_new"class="btn green">新增记录<iclass="fa fa-plus"></i> </button> </div> </div> </div> </div> <tableclass="table table-striped table-hover table-bordered"id="detail_editable_1"> <thead> <tr> <th>序号</th> <th> 费用类型 </th> <th> 发生时间 </th> <th> 费用金额(元) </th> <th> 费用说明 </th> <th> 编辑 </th> <th> 删除 </th> </tr> </thead> <tbody>@*<tr> <td> 1 </td> <td> 交通费 </td> <td> 2018-10-01 </td> <td> 2000 </td> <td> 备注信息 </td> <td> <aclass="edit"href="javascript:;"> 编辑 </a> </td> <td> <aclass="delete"href="javascript:;"> 删除 </a> </td> </tr>*@</tbody> </table> </div> </div>
其中主要是ID为 detail_editable_1 的标记,这个就是承载明细信息的表格,我们可以定义我们需要的表头信息,而输入框的内容,则可以通过dataTable插件的对象进行动态添加。
//定义dataTable对象 var table = $('#detail_editable_1');var oTable =table.dataTable({"lengthMenu": [
[5, 15, 20, -1],
[5, 15, 20, "All"] //改变每页的行数 ],//使用汉化 "language": {
url:'//cdn.datatables.net/plug-ins/3cfcc339e89/i18n/Chinese.json'},//初始化 "pageLength": 5,"columnDefs": [{ //设置默认列设置 'orderable': true,'targets': [0]
}, {"searchable": true,"targets": [0]
}],"order": [
[0, "asc"]
]//将第一列设置为asc的默认排序 });
编辑行记录,就是动态增加一些Input控件,让用户可以录入数据,如下代码所示。
//编辑行 functioneditRow(oTable, nRow) {var aData =oTable.fnGetData(nRow);var jqTds = $('>td', nRow);
jqTds[0].innerHTML = '<input type="text" class="form-control input-small" value="' + aData[0] + '" readonly>';
jqTds[1].innerHTML = '<input type="text" class="form-control input-small" value="' + aData[1] + '">';
jqTds[2].innerHTML = '<input type="date" class="form-control input-small" value="' + aData[2] + '">';
jqTds[3].innerHTML = '<input type="number" class="form-control input-small" value="' + aData[3] + '">';
jqTds[4].innerHTML = '<input type="text" class="form-control input-small" value="' + aData[4] + '">';
jqTds[5].innerHTML = '<a class="edit" href="">保存</a>';
jqTds[6].innerHTML = '<a class="cancel" href="">取消</a>';
}
保存数据后,通过把记录更新到对应TD对象里面,如下所示。
//费用类型 发生时间 费用金额 费用说明 var objList =[];//保存行数据,切换到普通模式 functionsaveRow(oTable, nRow) {var jqInputs = $('input', nRow);//更新行中每个input的值 oTable.fnUpdate(jqInputs[0].value, nRow, 0, false);
oTable.fnUpdate(jqInputs[1].value, nRow, 1, false);
oTable.fnUpdate(jqInputs[2].value, nRow, 2, false);
oTable.fnUpdate(jqInputs[3].value, nRow, 3, false);
oTable.fnUpdate(jqInputs[4].value, nRow, 4, false);
oTable.fnUpdate('<a class="edit" href="">编辑</a>', nRow, 5, false);
oTable.fnUpdate('<a class="delete" href="">删除</a>', nRow, 6, false);
oTable.fnDraw();
}
在界面上的几个出来动作按钮,如新增、编辑、保存、删除等按钮处理事件如下所示。
var addRow = 1;
$('#detail_editable_1_new').click(function(e) {
e.preventDefault();if (nNew &&nEditing) {if (confirm("前面记录没有保存,您是否需要保存?")) {
saveRow(oTable, nEditing);//$(nEditing).find("td:first").html("未保存"); nEditing = null;
nNew= false;
}else{
oTable.fnDeleteRow(nEditing);//cancel nEditing = null;
nNew= false;return;
}
}//添加一条新的记录 var aiNew = oTable.fnAddData([addRow++, '', '', '', '', '', '']);var nRow = oTable.fnGetNodes(aiNew[0]);
editRow(oTable, nRow);
nEditing=nRow;
nNew= true;
});//删除操作 table.on('click', '.delete', function(e) {
e.preventDefault();if (confirm("您确认要删除该行记录吗?") == false) {return;
}//获取上一级tr行的数据 var nRow = $(this).parents('tr')[0];var aData =oTable.fnGetData(nRow);var found = false;
$.each(objList,function(i, item) {if (item["seq"] == aData[0]) {
found= true;
objList.splice(i,1);
}
});
oTable.fnDeleteRow(nRow);
});//取消操作 table.on('click', '.cancel', function(e) {
e.preventDefault();if(nNew) {
oTable.fnDeleteRow(nEditing);
nEditing= null;
nNew= false;
}else{
restoreRow(oTable, nEditing);
nEditing= null;
}
});//编辑操作 table.on('click', '.edit', function(e) {
e.preventDefault();
nNew= false;/*获取所击连接的行对象*/ var nRow = $(this).parents('tr')[0];if (nEditing !== null && nEditing !=nRow) {/*当前正在编辑 - 但不是此行 - 在继续编辑模式之前恢复旧版*/restoreRow(oTable, nEditing);
editRow(oTable, nRow);
nEditing=nRow;
}else if (nEditing == nRow && this.innerHTML == "保存") {/*编辑该行,并准备保存记录*/saveRow(oTable, nEditing);
nEditing= null;
}else{/*No edit in progress - let's start one*/editRow(oTable, nRow);
nEditing=nRow;
}
});
}
我们在最后一步,提交数据的时候,就是遍历整个表格,获取每行的数据,并把它们放到JSON对象列表里面,在提交到后台录入即可,如下是获取列表数据的JS代码
//获取表格的数据,并返回对象列表 functionGetData() {var list =[];var trs =table.fnGetNodes();for (var i = 0; i < trs.length; i++) {var data = table.fnGetData(trs[i]);//获取指定行的数据 var obj ={};//obj["seq"] = data[0];//序号 obj["FeeType"] = data[1];
obj["OccurTime"] = data[2];
obj["FeeAmount"] = data[3];
obj["FeeDescription"] = data[4];
list.push(obj);
}returnlist;
};
获取到表格明细的数据后,我们就是确定如何提交到MVC后台接口来处理了,下面是业务里面关于明细数据提交MVC后台的JS代码。
后台MVC控制器的C#处理逻辑代码如下所示。
/// <summary> ///保存申请单主从表数据/// </summary> /// <returns></returns> [HttpPost]publicActionResult SaveApply(JObject param)
{dynamic obj =param;if (obj != null)
{var result = newCommonResult();if (obj.info != null)
{//获取主信息 var info = (JObject.FromObject(obj.info)).ToObject<ReimbursementInfo>();//转换为明细信息 List<ReimbursementDetailInfo> details = null;if (obj.details != null)
{
details= (JArray.FromObject(obj.details)).ToObject<List<ReimbursementDetailInfo>>();
}if (info != null)
{//修改部分信息 OnBeforeInsert(info);bool succeed = BLLFactory<Reimbursement>.Instance.Insert(info);if(succeed)
{if (details != null)
{foreach (var detailInfo indetails)
{//设置关键信息 detailInfo.Apply_ID =info.Apply_ID;
detailInfo.Header_ID=info.ID;
BLLFactory<ReimbursementDetail>.Instance.InsertUpdate(detailInfo, detailInfo.ID);
}
}
result.Success=succeed;
}
}
}returnToJsonContent(result);
}else{throw new MyApiException("传递参数错误");
}
}
其中对于提交上来的数据,对象信息用JObject进行转换,而对于明细列表则使用JArray.FromObject进行转换,其他部分就是如何保存主表和明细表的接口了。
上面的处理逻辑和代码就是处理明细表的前台获取,提交处理,以及后台的接口处理,整个过程主要用来介绍在Bootstrap开发框架中使用dataTable直接录入表格行数据。