Доступ к данным ячейки 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'));
}
}
}
Заранее спасибо!
3 ответа
Я вижу две проблемы в вашем коде. Первый более косметический, но правильное решение может упростить многие вещи в будущем.
Первая проблема заключается в том, что вы вручную добавляете строку "ВСЕГО" как часть данных сетки и вычисляете значения в строке внутри. calculateTotal
функция. Лучше всего использовать footerrow:true
опция, которая добавляет дополнительную строку внизу сетки, которая не будет смешана с данными сетки. Для данных на сервере вы можете использовать userdata
часть ответа JSON или XML с сервера и использование userDataOnFooter:true
дополнительно, чтобы обработать данные из userData
Параметр jqGrid для строки нижнего колонтитула. В случае "локального" типа данных можно использовать метод 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});
}
Теперь к вашей главной проблеме. Вы используете режим редактирования ячейки. Если функция calculateTotal
(ваша оригинальная или моя упрощенная версия) будет вызываться в тот момент, когда одна из ячеек "сумма" или "налог" находится в режиме редактирования, calculateTotal
будет прочитан фрагмент HTML с <input>
Элемент вместо строки с номером и расчет не удастся.
Я создал небольшое демо, которое называют 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});
}
Соответствующее исправленное демо вы найдете здесь. В вашем окончательном коде вы можете удалить
setInterval(calculateTotal, 1000);
который я использовал только для демонстрационных целей и обновить нижний колонтитул в 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});
};
Спасибо, олег, решение для меня было применение и изменение того, что вы положили
var ListTabla="ListFormatos";
var request="../../tabla_general/tabla_general_mantenimiento.php";
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(grid) {
total_hpr_suebas = retorna_suma('hpr_suebas',grid);
total_hpr_asifam = retorna_suma('hpr_asifam',grid);
total_hpr_bashpr = retorna_suma('hpr_bashpr',grid);
total_hpr_remcom = retorna_suma('hpr_remcom',grid);
total_hpr_basmes = retorna_suma('hpr_basmes',grid);
total_hpr_provcts = retorna_suma('hpr_provcts',grid);
total_hpr_provgrat = retorna_suma('hpr_provgrat',grid);
total_hpr_provvac=retorna_suma('hpr_provvac',grid);
$("#"+grid).jqGrid('footerData','set',{sec_detsec:'TOTAL',hpr_suebas:total_hpr_suebas,hpr_asifam:total_hpr_asifam,hpr_bashpr:total_hpr_bashpr,hpr_remcom:total_hpr_remcom,hpr_basmes:total_hpr_basmes,hpr_provcts:total_hpr_provcts,hpr_provgrat:total_hpr_provgrat,hpr_provvac:total_hpr_provvac});
};
retorna_suma=function(campo,grid)
{
total=0;
i=getColumnIndexByName(grid,campo);
$("tbody > tr.jqgrow > td:nth-child("+(i+1)+")",$("#"+grid)[0]).each(function() {
total+= Number(getTextFromCell(this));
});
return total;
}
function fn_jqgrid_history_provisiones_trabajador(tra_idtra,fecha_inicio,fecha_fin)
{
jQuery("#"+ListTabla).jqGrid({
url:request+"?action=search_history_provisiones_trabajador&tra_idtra="+tra_idtra+"&fecha_inicio="+fecha_inicio+"&fecha_fin="+fecha_fin,
async: false,
datatype: 'json',
colNames:['','ID','SECTOR','BASICO','ASIG. FAM','DIAS','BASE','REM. COMP.','BASE MES','P.CTS','P.GRAT.','P.VAC.','MES','ANIO','PORC.','SAL.VAC.','SAL.GRAT.'],
colModel:[
{name:'act', index:'act', width:50, resizable:true, align:"center",hidden:true},
{name:'id', index:'id', width:50, resizable:true, align:"center",hidden:true},
{name:'sec_detsec', index:'sec_detsec', width:80},
{name:'hpr_suebas', index:'hpr_suebas', width:60},
{name:'hpr_asifam', index:'hpr_asifam', width:50},
{name:'hpr_numdia', index:'hpr_numdia', width:30},
{name:'hpr_bashpr',index:'hpr_bashpr', width:60},
{name:'hpr_remcom,',index:'hpr_remcom', width:60},
{name:'hpr_basmes', index:'hpr_basmes', width:60},
{name:'hpr_provcts', index:'hpr_provcts', width:60},
{name:'hpr_provgrat', index:'hpr_provgrat', width:60},
{name:'hpr_provvac', index:'hpr_provvac', width:60},
{name:'hpr_meshpr', index:'hpr_meshpr', width:30},
{name:'hpr_aniohpr,',index:'hpr_aniohpr', width:30},
{name:'hpr_salpor', index:'hpr_salpor', width:50},
{name:'hpr_salval_vac', index:'hpr_salval_vac', width:50},
{name:'hpr_salval_grat', index:'hpr_salval_grat', width:50}
],
pager: '#paginacion',
rowNum:10,
rowList:[10,20,30],
sortname: 'ID',
ondblClickRow:function(rowid, iRow, iCol, e)
{
obj=jQuery("#"+ListTabla).jqGrid('getRowData',rowid);
}
,
sortorder: 'desc',
editurl:request,
viewrecords: true,
caption: 'Provisiones',
//rownumbers: true,
height: 250,
rowheight: 280,
footerrow : true,
gridComplete: function () {
calculateTotal(ListTabla);
},
afterSaveCell: function (rowid, name, val, iRow, iCol) {
//calculateTotal(ListTabla);
}
}).navGrid('#paginacion',{add:false,edit:false, del:false});
jQuery("#"+ListTabla).jqGrid('bindKeys', {"onEnter":function( rowid ) {
obj=jQuery("#"+ListTabla).jqGrid('getRowData',rowid);
} } );
}
Если вы просто хотите пересчитать общее число, вы можете использовать триггер для перезагрузки сетки в событии afterSaveCell. Как это:
afterSaveCell: function (rowid, name, val, iRow, iCol)
{
jQuery("#list11").jqGrid('setGridParam',{datatype:'local',loadonce:true}).trigger('reloadGrid');
}