I have a Pivot Grid defined and I was trying to enable real-time editing of cells (the Fund field) at the detail level. I have tried implementing both the setInterval method as well as the grid's "change" function. In both cases, changes are not being detected. The isDirty method is being checked but always returns a false in the savePreSapChanges function. Additionally, a test in debug mode of the grid.getChanges is always showing no changes. (see attached) My preference would be to utilize the grid's Change function rather than setting a timer interval, but in either case the grid.getChanges function always returns an empty result.
Below is the code I am using, if you can you tell me what I am missing to enable the Grid's change event I would greatly appreciate it...
$(function () {
var interval2;
function savePreSapChanges() {
/**
1. if there is no active ajax request.
2. there is no ongoing editing in the grid.
3. grid is dirty.
4. all changes are valid.
*/
//debugger
if (!$.active && !grid4.getEditCell().$cell && grid4.isDirty() && grid4.isValidChange({ allowInvalid: true }).valid) {
var SapGridChanges = grid4.getChanges({ format: 'byVal' });
debugger
$.ajax({
url: '/STS/Content/files/code/gridEditsSAP.cfc', // for ColdFusion
data: {
method: "realtimeEdit",
list: JSON.stringify( SapGridChanges )
},
dataType: "json",
type: "POST",
async: true,
beforeSend: function (jqXHR, settings) {
grid4.option("strLoading", "Saving..");
grid4.showLoading();
},
success: function (changes) {
//commit the changes.
grid4.commit({ type: 'add', rows: changes.addList });
grid4.commit({ type: 'update', rows: changes.updateList });
grid4.commit({ type: 'delete', rows: changes.deleteList });
},
complete: function () {
grid4.hideLoading();
grid4.option("strLoading", $.paramquery.pqGrid.defaults.strLoading);
grid4.refreshDataAndView();
}
});
}
}
//save changes from a timer.
interval2 = setInterval(savePreSapChanges, 1000);
function groupChg(val){
var lower = Math.floor( val/ 10 ) * 10,
upper = Math.ceil( (val + 1)/ 10 ) * 10;
return lower + " < " + upper;
};
var colSAP = [
//extra column to show grouping (for both pivot and row grouping mode, used along with groupModel.titleIndx )
{title: 'GL Account', tpHide: true, menuInHide: true, dataIndx: 'grp'},
{title: "Account Name", width: 130, dataIndx: "GLName", filter:{groupIndx: 'GLAccount'} },
{title: "G/L Code", width: 110, dataIndx: "GLAccount", hidden: "true"},
{title: "FAS Activity", width: 150, dataIndx: "Activity"},
{title: "Region", width: 120, dataIndx: "Region", dataType: "string"},
{title: "Country", width: 120, dataIndx: "Country", dataType: "string"},
{title: "Project", width: 120, dataIndx: "Project", dataType: "string"},
{title: "Total", width: 120, dataIndx: "OrigAmt", dataType: "float", format: '$##,###.00', summary: {type: "sum" }},
{title: "% Share", width: 120, dataIndx: "pctToTotal", dataType: "float", format: '##.00%', summary: {type: "sum" }},
{title: "Fund", width: 110, dataIndx: "Fund", dataType: "string", editable: true}
];
colSAP.forEach(function(col){
col.menuIcon = true;
col.filter = { condition: 'range'};
})
var SAPgroupModel = {
on: true, // grouping mode.
pivot: false, // pivotMode
checkbox: true,
checkboxHead: true,
select: true,
titleIndx: 'grp', // v7.0.0: new option instead of titleInFirstCol
indent: 20,
fixCols: false,
groupCols: ['GLAccount'], // grouping along column axis.
header: false, // hide grouping toolbar.
grandSummary: true, // show grand summary row.
dataIndx: ['GLAccount'], // grouping along row axis.
collapsed: [ true ],
useLabel: true,
summaryEdit: false
};
var SAPdataModel = {
cache: true,
location: "remote",
sortDir: "down",
sorting: "local",
dataType: "xml",
url: "/sts/content/files/data/rawdata.xml",
getData: function (dataDoc) {
//debugger;
var obj = { itemParent: "item", itemNames: ["GLAccount","GLName","OrigAmt","pctToTotal","Fund","Activity","Region","Country","Project"]};
return { data: $.paramquery.xmlToJson(dataDoc, obj) };
}
};
var obj = {
height: 500,
dataModel: SAPdataModel,
groupModel: SAPgroupModel,
colModel: colSAP,
sortModel: { sorter:[{dataIndx: 'glcode'}] },
editor: { select: true, type: 'textbox' },
trackModel: { on: true }, // to turn on the track changes.
postRenderInterval: -1, // synchronous post render.
numberCell: {width: 50},
freezeCols: 1,
flex:{one: true},
rowBorders: false,
formulas: [
['pct', function (rd) {
var val = rd.amount/700000;
}]
],
summaryTitle: {
sum: ""
},
change: function (evt, ui) {
alert('Change Made');
debugger
var gridChanges3 = grid.getChanges({ format: 'byVal' });
savePreSapChanges();
},
destroy: function () {
//clear the interval upon destroy.
//clearInterval(interval2);
},
showTitle: false,
wrap: false,
hwrap:false,
editable: true,
toolPanel:{
show: false //show toolPanel initially.
},
toolbar: {
cls: 'pq-toolbar-export',
items: [
{
type: 'button',
label: "Export to Excel(xlsx)",
icon: 'ui-icon-document',
listener: function (evt) {
var str = this.exportExcel({render: true });
saveAs(str, "pivot.xlsx");
}
},
{
type: 'button',
label: "Toolbar Panel",
icon: 'ui-icon-wrench',
listener: function (evt) {
this.ToolPanel().toggle();
}
},
{
type: 'textbox',
label: "Filter: ",
attr:'placeholder="Enter text"',
listener:{timeout: function (evt) {
var txt = $(evt.target).val();
var rules = this.getCMPrimary().map(function(col){
return {
dataIndx: col.dataIndx,
condition:'contain',
value: txt
}
})
this.filter({
mode: 'OR',
rules:rules
})
}}
}
]
},
//use pivotCM event to make grouped columns collapsible.
pivotCM: function(evt, ui) {
//add collapsible to grouped parent columns.
this.Columns().each(function(col){
var cm = col.colModel
if(cm && cm.length>1 && !col.collapsible)
col.collapsible = {on: true, last: true};
}, ui.CM);
}
};
var grid4 = pq.grid( "#SAPPre", obj);
});