jqGrid在编辑时访问单元格数据 [英] jqGrid access cell data while it is being edited

查看:145
本文介绍了jqGrid在编辑时访问单元格数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm currently using afterSaveCell to handle manually updating some cells in a grid. I have this working fine if the user uses enter to save the currently editing cell.

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

Unfortunately, if they click or tab out of the cell they are editing directly into another cell I can no longer grab the cell value of the newly edited cell as getCell will only return the html for the input control.

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

In summary, is there any way to access the value of the cell even while it is being edited?

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'));
        }
    }
}

提前致谢!

推荐答案

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

I see two problems in your code. The first one is more cosmetic, but the correct solution can simplify many things in the future.

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

The first problem is that you add manual the "TOTAL" row as a part of grid data and calculate the values in the row inside calculateTotal function. The better way is to use footerrow:true option, which add additional row at the bottom of grid which will be not mixed with the grid data. For server based data you can use userdata part of JSON or XML response from the server and use userDataOnFooter:true additionally to till the data from the userData jqGrid parameter to the footer row. In case of "local" datatype one can use footerData method to set (or get) the data in the footer. Additionally the method getCol can be used co calculate the sum of elements in the column. So your version of calculateTotal function can be rewritten as

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});
}

现在解决您的主要问题。您使用单元格编辑模式。如果函数 calculateTotal (您的原始版本或我的简化版本)将在金额或税金单元格中的一个处于编辑模式时被调用, calculateTotal 将被读取带有< input> 元素的HTML片段,而不是带有数字和计算的字符串将失败。

Now to your main problem. You use cell edit mode. If the function calculateTotal (your original or my simplified version) will be called at the time when one from the cells of the 'amount' or 'tax' are in the editing mode, the calculateTotal will be read HTML fragment with <input> element instead of the string with the number and the calculation will failed.

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

I created the small demo which call calculateTotal every second. So if you click on any cell from the 'amount' or 'tax' column you will see that in the footer row 0 will be displayed as the sum. So the demo having cellsubmit:'clientArray' has the same problem as in your original code with cellsubmit:'remote'.

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

To solve the problem one can use data parameter of jqGrid during the sum calculation:

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});
}

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

The corresponding fixed demo you will find here. In your final code you can remove

setInterval(calculateTotal, 1000);

我仅用于演示目的并刷新 afterSaveCell 仅限事件处理程序。

which I used for demonstration purpose only and refresh the footer in the afterSaveCell event handler only.

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

UPDATED: If you work with remote data you can not use data parameter. So one have to get data from the <input> element if needed. I created one more demo which demonstrate how one can do this. The code of calculateTotal will be longer:

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});
};

这篇关于jqGrid在编辑时访问单元格数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆