jqGrid在编辑时访问单元格数据

Sha*_*awn 6 javascript jquery jqgrid

我目前正在使用afterSaveCell手动更新网格中的某些单元格.如果用户使用enter保存当前编辑的单元格,我可以正常工作.

不幸的是,如果他们点击或跳出单元格,他们正在直接编辑到另一个单元格,我不能再抓取新编辑的单元格的单元格值,因为getCell只返回输入控件的html.

总之,即使在编辑单元格时,有没有办法访问单元格的值?

jQuery(document).ready(function () {
    var mydata = [
        {id:"1", invdate:"2007-10-01",name:"test",  note:"note",  amount:"200.00",tax:"10.00",total:"210.00"},
        {id:"2", invdate:"2007-10-02",name:"test2", note:"note2", amount:"300.00",tax:"20.00",total:"320.00"},
        {id:"3", invdate:"2007-09-01",name:"test3", note:"note3", amount:"400.00",tax:"30.00",total:"430.00"},
        {id:"4", invdate:"2007-10-04",name:"test",  note:"note4", amount:"200.00",tax:"10.00",total:"210.00"},
        {id:"5", invdate:"2007-10-05",name:"test5", note:"note5", amount:"300.00",tax:"20.00",total:"320.00"},
        {id:"6", invdate:"2007-09-06",name:"test",  note:"note6", amount:"400.00",tax:"30.00",total:"430.00"},
        {id:"7", invdate:"2007-10-04",name:"test7", note:"note7", amount:"200.00",tax:"10.00",total:"210.00"},
        {id:"8", invdate:"2007-10-03",name:"test8", note:"note8", amount:"300.00",tax:"20.00",total:"320.00"},
        {id:"9", invdate:"2007-09-01",name:"test",  note:"note9", amount:"400.00",tax:"30.00",total:"430.00"},
        {id:"10",invdate:"2007-09-08",name:"test10",note:"note10",amount:"500.00",tax:"30.00",total:"530.00"},
        {id:"11",invdate:"2007-09-08",name:"test11",note:"note11",amount:"500.00",tax:"30.00",total:"530.00"},
        {id:"12",invdate:"",name:"TOTAL",  note:"",amount:"",tax:"",total:""}
    ];

    var grid = $("#list");

    grid.jqGrid({
        cellsubmit: 'remote',
        cellurl: '/Example/GridSave',
        datatype: "local",
        data: mydata,
        mtype: 'POST',
        colNames: ['Inv No', 'Date', 'Client', 'Amount', 'Tax', 'Total', 'Notes'],
        colModel: [
            { name: 'id', index: 'id', width: 65, sorttype: 'int', hidden: true },
            { name: 'invdate', index: 'invdate', width: 120, align: 'center', formatter: 'date', formatoptions: { newformat: 'd-M-Y' }, sortable: false },
            { name: 'name', index: 'name', editable: true, width: 90, sortable: false },
            { name: 'amount', index: 'amount', editable: true, width: 70, formatter: 'number', align: 'right', sortable: false },
            { name: 'tax', index: 'tax', editable: true, width: 60, formatter: 'number', align: 'right', sortable: false },
            { name: 'total', index: 'total', editable: true, width: 60, formatter: 'number', align: 'right', sortable: false },
            { name: 'note', index: 'note', width: 100, sortable: false }
        ],
        rowNum: 1000,
        pager: '#pager',
        viewrecords: true,
        sortorder: "desc",
        caption: "afterSaveCell Issue",
        height: "100%",
        cellEdit: true,
        gridComplete: function () {
            calculateTotal();
        },
        afterSaveCell: function (rowid, name, val, iRow, iCol) {
            calculateTotal();
        }
    });
});

function calculateTotal() {
    var totalAmount = 0;
    var totalTax = 0;

    var grid = jQuery("#list");

    var ids = grid.jqGrid('getDataIDs');
    for (var i = 0; i < ids.length; i++) {
        var id = ids[i];

        if (grid.jqGrid('getCell', id, 'name') === "TOTAL") {
            grid.jqGrid('setRowData', id, {
                'amount': totalAmount,
                'tax': totalTax,
                'total': totalAmount + totalTax
            });
        }
        else {
            totalAmount += Number(grid.jqGrid('getCell', id, 'amount'));
            totalTax += Number(grid.jqGrid('getCell', id, 'tax'));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Ole*_*leg 11

我在你的代码中看到了两个问题.第一个是更美观,但正确的解决方案可以简化未来的许多事情.

第一个问题是您将"TOTAL"行手动添加为网格数据的一部分,并计算calculateTotal函数内部行中的值.更好的方法是使用footerrow:true选项,它在网格底部添加额外的行,不会与网格数据混合.对于基于服务器的数据,您可以使用userdata来自服务器的部分JSON或XML响应,并userDataOnFooter:true另外使用以将数据从userDatajqGrid参数添加到页脚行.在"本地"数据类型的情况下,可以使用footerData方法设置(或获取)页脚中的数据.另外,可以使用方法getCol来计算列中元素的总和.因此,您的calculateTotal函数版本可以重写为

var grid = $("#list");
var calculateTotal = function() {
    var totalAmount = grid.jqGrid('getCol','amount',false,'sum'),
        totalTax = grid.jqGrid('getCol','tax',false,'sum');
    grid.jqGrid('footerData','set',{name:'TOTAL',amount:totalAmount,tax:totalTax});
}
Run Code Online (Sandbox Code Playgroud)

现在来看你的主要问题.您使用单元格编辑模式.如果在calculateTotal'amount'或'tax'的单元格中的一个处于编辑模式时将调用该函数(您的原始版本或我的简化版本),则将calculateTotal使用<input>元素而不是带有元素的字符串读取HTML片段数字和计算将失败.

我创建calculateTotal每秒调用一次的小型演示.因此,如果您点击"金额"或"税"列中的任何单元格,您会看到页脚行0将显示为总和.因此,演示具有cellsubmit:'clientArray'与原始代码中相同的问题cellsubmit:'remote'.

要解决这个问题,可以data在求和过程中使用jqGrid的参数:

var grid = $("#list");
var calculateTotal = function() {
    var gridData = grid.jqGrid('getGridParam','data'),
        i=0,totalAmount=0,totalTax=0;
    for (;i<gridData.length;i++) {
        var rowData = gridData[i];
        totalAmount += Number(rowData.amount);
        totalTax += Number(rowData.tax);
    }
    grid.jqGrid('footerData','set',{name:'TOTAL',amount:totalAmount,tax:totalTax});
}
Run Code Online (Sandbox Code Playgroud)

你会在这里找到相应的固定演示.在您的最终代码中,您可以删除

setInterval(calculateTotal, 1000);
Run Code Online (Sandbox Code Playgroud)

我仅用于演示目的,仅刷新afterSaveCell事件处理程序中的页脚.

更新:如果使用远程数据,则无法使用data参数.因此,<input>如果需要,必须从元素中获取数据.我创建了另一个演示,演示了如何做到这一点.代码calculateTotal将更长:

var getColumnIndexByName = function(grid,columnName) {
    var cm = grid.jqGrid('getGridParam','colModel');
    for (var i=0,l=cm.length; i<l; i++) {
        if (cm[i].name===columnName) {
            return i; // return the index
        }
    }
    return -1;
},
getTextFromCell = function(cellNode) {
    return cellNode.childNodes[0].nodeName === "INPUT"?
           cellNode.childNodes[0].value:
           cellNode.textContent || cellNode.innerText;
},
calculateTotal = function() {
    var totalAmount = 0, totalTax = 0,
        i=getColumnIndexByName(grid,'amount');
    $("tbody > tr.jqgrow > td:nth-child("+(i+1)+")",grid[0]).each(function() {
        totalAmount += Number(getTextFromCell(this));
    });

    i=getColumnIndexByName(grid,'tax');
    $("tbody > tr.jqgrow > td:nth-child("+(i+1)+")",grid[0]).each(function() {
        totalTax += Number(getTextFromCell(this));
    });

    grid.jqGrid('footerData','set',{name:'TOTAL',amount:totalAmount,tax:totalTax});
};
Run Code Online (Sandbox Code Playgroud)