jqGrid access cell data while it is being edited(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
选项,它在网格底部添加额外的行,这将与网格数据不混合.对于基于服务器的数据,您可以使用来自服务器的 JSON 或 XML 响应的 userdata
部分,并另外使用 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
每秒.因此,如果您单击'amount' 或 'tax' 列,您将看到在页脚行 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.
已更新:如果您使用远程数据,则不能使用 data
参数.因此,如果需要,必须从 <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 在编辑时访问单元格数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:jqGrid 在编辑时访问单元格数据
基础教程推荐
- 自定义 XMLHttpRequest.prototype.open 2022-01-01
- html表格如何通过更改悬停边框来突出显示列? 2022-01-01
- Vue 3 – <过渡>渲染不能动画的非元素根节点 2022-01-01
- 如何使用TypeScrip将固定承诺数组中的项设置为可选 2022-01-01
- 用于 Twitter 小部件宽度的 HTML/CSS 2022-01-01
- Chart.js 在线性图表上拖动点 2022-01-01
- 如何使用JIT在顺风css中使用布局变体? 2022-01-01
- 直接将值设置为滑块 2022-01-01
- Electron 将 Node.js 和 Chromium 上下文结合起来意味着 2022-01-01
- 我可以在浏览器中与Babel一起使用ES模块,而不捆绑我的代码吗? 2022-01-01