在Bootstrap开发框架中使用dataTable直接录入表格行数据

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

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

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

image

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

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

image

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

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

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

image

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

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

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

image

界面视图的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代码。

image

后台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直接录入表格行数据。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容