在Winform开发的时候,我们很多时候可以利用表格控件来直接录入数据,不过在Web上较少看到,其实也可以利用dataTable对象处理直接录入表格行数据,这个可以提高数据的录入方便,特别是在一些简单业务的明细数据的时候,看起来会比弹出窗口录入方便一些,也高大上一点。本篇主要介绍在Bootstrap开发框架中使用dataTable直接录入表格行数据。

1、基于表格直接录入数据和Winform的界面回顾

在开始Web界面直接录入表格行数据前,我们先来看看Winform界面的处理情况,如我在流程管理里面,对于具有主从明细的报销业务表的数据处理,采用了下面的界面。

这种明细表单可以直接在表格控件Griview上进行新增、编辑处理。

而对于Web界面,如果我们要保持和这个布局类似的话,采用dataTable直接录入表格行数据也可以达到。

上面的界面处理明细数据的时候,可以直接使用新增记录,直接在录入框中输入数据,然后保存起来,保存后数据变为只读,如果需要修改,还可以单击编辑按钮进行修改。

而这些明细的数据,也仅仅存在JS的对象里面,还没有保存到后台数据库中,我们可以在最后保存(如上界面的确定按钮)处理中再获取全部添加的数据进行提交即可。

在这些数据提交之后,我们在查看界面里面可以可以Bootstrap Table插件来展示数据即可。

2、在Web上使用dataTable直接录入表格行数据的实现

上面的界面展示了在Web上使用dataTable直接录入表格行数据和数据展示,这里开始介绍它们的界面和实现代码。

界面部分主要是这个明细的处理。

界面视图的HTML代码如下所示。

<div class="portlet light portlet-fit ">
<div class="portlet-title">
<div class="caption">
<i class="icon-settings font-red"></i>
<span class="caption-subject font-red sbold uppercase">明细清单</span>
</div>
</div>
<div class="portlet-body">
<div class="table-toolbar">
<div class="row">
<div class="col-md-6">
<div class="btn-group">
<button id="detail_editable_1_new" class="btn green">
新增记录
<i class="fa fa-plus"></i>
</button>
</div>
</div>
</div>
</div>
<table class="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>
<a class="edit" href="javascript:;"> 编辑 </a>
</td>
<td>
<a class="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控件,让用户可以录入数据,如下代码所示。

                //编辑行
function editRow(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 = [];
//保存行数据,切换到普通模式
function saveRow(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代码

            //获取表格的数据,并返回对象列表
function GetData() {
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);
}
return list;
};

获取到表格明细的数据后,我们就是确定如何提交到MVC后台接口来处理了,下面是业务里面关于明细数据提交MVC后台的JS代码。

后台MVC控制器的C#处理逻辑代码如下所示。

        /// <summary>
/// 保存申请单主从表数据
/// </summary>
/// <returns></returns>
[HttpPost]
public ActionResult SaveApply(JObject param)
{
dynamic obj = param;
if (obj != null)
{
var result = new CommonResult(); 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 in details)
{
//设置关键信息
detailInfo.Apply_ID = info.Apply_ID;
detailInfo.Header_ID = info.ID;
BLLFactory<ReimbursementDetail>.Instance.InsertUpdate(detailInfo, detailInfo.ID);
}
}
result.Success = succeed;
}
}
}
return ToJsonContent(result);
}
else
{
throw new MyApiException("传递参数错误");
}
}

其中对于提交上来的数据,对象信息用JObject进行转换,而对于明细列表则使用JArray.FromObject进行转换,其他部分就是如何保存主表和明细表的接口了。

上面的处理逻辑和代码就是处理明细表的前台获取,提交处理,以及后台的接口处理,整个过程主要用来介绍在Bootstrap开发框架中使用dataTable直接录入表格行数据。

在Bootstrap开发框架中使用dataTable直接录入表格行数据的更多相关文章

  1. 在Bootstrap开发框架中使用dataTable直接录入表格行数据(2)--- 控件数据源绑定

    在前面随笔<在Bootstrap开发框架中使用dataTable直接录入表格行数据>中介绍了在Web页面中使用Jquery DataTable插件进行对数据直接录入操作,这种处理能够给用户 ...

  2. 在Bootstrap开发框架中使用Grid++报表

    之前在随笔<在Winform开发中使用Grid++报表>介绍了在Winform环境中使用Grid++报表控件,本篇随笔介绍在Bootstrap开发框架中使用Grid++报表,也就是Web环 ...

  3. 在Bootstrap开发框架中使用bootstrapTable表格插件和jstree树形列表插件时候,对树列表条件和查询条件的处理

    在我Boostrap框架中,很多地方需要使用bootstrapTable表格插件和jstree树形列表插件来共同构建一个比较常见的查询界面,bootstrapTable表格插件主要用来实现数据的分页和 ...

  4. sql中根据逗号分隔,查出多行数据

    --sql中根据逗号分隔,查出多行数据 select       a.DiscussID,b.LocationID  from       (select DiscussID,LocationID=c ...

  5. 在Winform开发框架中,利用DevExpress控件实现数据的快速录入和选择

    在实际的项目开发过程中,有好的控件或者功能模块,我都是想办法尽可能集成到我的WInform开发框架中,这样后面开发项目起来,就可以节省很多研究时间,并能重复使用,非常高效方便.在我很早之前的一篇博客& ...

  6. 在Bootstrap开发框架中使用bootstrap-datepicker插件

    在基于Boostrap的Web开发中,往往需要录入日期内容,基于Boostrap的插件中,关于日期的录入可以使用bootstrap-datepicker这个非常不错的插件,以替代默认的type=dat ...

  7. 基于Metronic的Bootstrap开发框架经验总结(15)-- 更新使用Metronic 4.75版本

    在基于Metronic的Bootstrap开发框架中,一直都希望整合较新.较好的前端技术,结合MVC的后端技术进行项目的开发,随着时间的推移,目前Metronic也更新到了4.75版本,因此着手对这个 ...

  8. 基于Metronic的Bootstrap开发框架经验总结(16)-- 使用插件bootstrap-table实现表格记录的查询、分页、排序等处理

    在业务系统开发中,对表格记录的查询.分页.排序等处理是非常常见的,在Web开发中,可以采用很多功能强大的插件来满足要求,且能极大的提高开发效率,本随笔介绍这个bootstrap-table是一款非常有 ...

  9. Vue&Element开发框架中增加工作流处理,查看申请单中整合多个处理类型的处理

    关于我在Winform框架.混合框架.Bootstrap开发框架中的简易审批性工作流模块,我写过不少文章,有兴趣可以参考<工作流模块>的随笔进行了解,本篇随笔在完成了Vue&Ele ...

随机推荐

  1. Supervisor 为服务创建守护进程

    今天需要再服务上部署一个.net 方面的项目:当时开启服务的命令只能在前台执行:使用nohub CMD &等放在后台开启服务都会宕机:所以搜寻了Supervisor 这个解决办法,为服务创建守 ...

  2. SpringCloud学习(二):微服务入门实战项目搭建

    一.开始使用Spring Cloud实战微服务 1.SpringCloud是什么? 云计算的解决方案?不是 SpringCloud是一个在SpringBoot的基础上构建的一个快速构建分布式系统的工具 ...

  3. 【响应式编程的思维艺术】 (3)flatMap背后的代数理论Monad

    目录 一. 划重点 二. flatMap功能解析 三. flatMap的推演 3.1 函数式编程基础知识回顾 3.2 从一个容器的例子开始 3.3 Monad登场 3.4 对比总结 3.5 一点疑问 ...

  4. 第33章 密码学(Cryptography),密钥(Keys)和HTTPS - Identity Server 4 中文文档(v1.0.0)

    IdentityServer依赖于几个加密机制来完成它的工作. 33.1 令牌签名和验证 IdentityServer需要非对称密钥对来签署和验证JWT.此密钥对可以是证书/私钥组合或原始RSA密钥. ...

  5. C# winform在关闭窗体的时候及时释放内存问题

    winform中如果每次打开的窗体都是通过new出来的,发现几次过后就会出现提示”内存不足“问题,那么在关闭窗体的时候怎么处理可以及时释放内存?dispose方法可能也无法解决这个问题.我们可以每次在 ...

  6. Elasticsearch系列(3):Elasticsearch操作入门

    创建Index 新建Index,可以直接向Elastic服务器发送PUT请求,比如下面的命令创建了一个名为:logdb的Index. [root@elsearchserver ~]# curl -X ...

  7. java servlet的执行流程

    1.先附上代码如下 Servlet1.java public class Servlet1 implements Servlet { @Override public void init(Servle ...

  8. splay详解(三)

    前言 上一节我们学习了splay所能解决的基本问题,这节我来讲一下splay怎么搞区间问题 实现 splay搞区间问题非常简单,比如我们要在区间$l,r$上搞事情,那么我们首先把$l$的前驱旋转到根节 ...

  9. Dynamics 365新特性介绍:在视图中显示图片和提示

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复242或者20161230可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...

  10. ios手机录屏软件哪个好

    苹果手机中的airplay镜像,是苹果手机系统的一大特色,可以轻松把手机屏幕投射电脑,这个功能使苹果手机相较安卓手机投屏会更加轻松,那么如何实现苹果手机投射电脑屏幕?下面小编便来分享ios手机录屏软件 ...