jQWidgets Forums
jQuery UI Widgets › Forums › Grid › Bug with Filter and Edit
This topic contains 17 replies, has 4 voices, and was last updated by Peter Stoev 11 years, 2 months ago.
-
AuthorBug with Filter and Edit Posts
-
Hi,
I stumpled upon a bug that I could reproduce with one of your examples.
I used your example: http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxgrid/cellediting.htm?classic
I then added the jqxgrid.filter.js and set filterable: true for the grid.
In the updaterow function I used console.log(rowid)
Now, if I edit the table without filter, the rowid works correctly. If I filter the table so that the first entry of the original data is displayed and I change something there, the rowid 0 is displayed or sometimes if I filter and change any entry the rowid is displayed correctly. But most of the times the rowid is null and that’s a weird bug. My workaround is using the corresponding datafield from the rowdata, for my purposes that works.
Could you please verify that behaviour?
Hello Klaus H,
We are aware of the reported issue and will fix it as soon as possible.
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Hello,
thanks for the version 2.8.1, the issue is fixed.
Unfortunately I found a new issue in the updaterow function.
I have a field save in my rowdata that is by default 0 and when the updaterow function is called I set it to 1. The representing grid column has a cellsrenderer that displays text representing the state. So when I change one column in the grid the updaterow function is called, the attribute is changed, the cellsrenderer is triggered and the column is displayed correctly.
Now if I have a filter active, the updaterow function is called, but the attribute value is not changed and of course the cellsrenderer not triggered. I have tried it with the rowdata parameter from the updaterow function call and with getting the rowdata via the function getrowdatabyid. Both solutions work when the filter is not active, but not when there is a filter.
Could you please verify that?
Kind Regards.
Hello Klaus H,
When you edit a cell, only the cell’s value is changed and updated in the Grid. The “updaterow” function should be used only for synchronization with a server and you should not try to update other cell values from the row in that function. If you wish to update a row, use the “updaterow” method of jqxGrid.
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Hello Dimitar,
thanks for the advice.
I now use the updaterow method of the jqxGrid in the updaterow function, but the behaviour does not change.
I have three possibilities:
a) change in rowdata parameter
b) change in rowdata parameter and invoke updaterowmethod in addition
c) using getrowdatabyid method to get the data and updaterow methodAs long as I have no filter active, the row updates in all cases.
If I have an active filter there is no update in either case.
My expectation was the behaviour should be the same if I use a filter or not.
Kind Regards,
KlausHi Klaus,
Could you please, provide a sample which demonstrates the behavior which you describe? If there is something wrong in the posted code, we will resolve it or if it is an issue on our side we will add a work item.
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Hello Dimitar,
no problem, I used the example http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxgrid/cellediting.htm as base for the following code (I hope it will be shown correctly), modfied the generatedata so the save attribute is initialized and added pager, filter and sorting. I also use a JavaScript array saveRows with an additional function in_array.
I have all three possible solutions I came up with in the updaterow function and I recreated the behaviour mentioned above:
$(document).ready(function () { var saveRows = new Array(); Array.prototype.in_array = function(needle) { for(var i=0; i < this.length; i++) if(this[ i] === needle) return true; return false; } function generatedata(rowscount, hasNullValues) { // prepare the data var data = new Array(); if (rowscount == undefined) rowscount = 100; var firstNames = [ "Andrew", "Nancy", "Shelley", "Regina", "Yoshi", "Antoni", "Mayumi", "Ian", "Peter", "Lars", "Petra", "Martin", "Sven", "Elio", "Beate", "Cheryl", "Michael", "Guylene" ]; var lastNames = [ "Fuller", "Davolio", "Burke", "Murphy", "Nagase", "Saavedra", "Ohno", "Devling", "Wilson", "Peterson", "Winkler", "Bein", "Petersen", "Rossi", "Vileid", "Saylor", "Bjorn", "Nodier" ]; var productNames = [ "Black Tea", "Green Tea", "Caffe Espresso", "Doubleshot Espresso", "Caffe Latte", "White Chocolate Mocha", "Caramel Latte", "Caffe Americano", "Cappuccino", "Espresso Truffle", "Espresso con Panna", "Peppermint Mocha Twist" ]; var priceValues = [ "2.25", "1.5", "3.0", "3.3", "4.5", "3.6", "3.8", "2.5", "5.0", "1.75", "3.25", "4.0" ]; for (var i = 0; i < rowscount; i++) { var row = {}; var productindex = Math.floor(Math.random() * productNames.length); var price = parseFloat(priceValues[productindex]); var quantity = 1 + Math.round(Math.random() * 10); row["id"] = i; row["available"] = productindex % 2 == 0; if (hasNullValues == true) { if (productindex % 2 != 0) { var random = Math.floor(Math.random() * rowscount); row["available"] = i % random == 0 ? null : false; } } row["save"] = 0; row["firstname"] = firstNames[Math.floor(Math.random() * firstNames.length)]; row["lastname"] = lastNames[Math.floor(Math.random() * lastNames.length)]; row["name"] = row["firstname"] + " " + row["lastname"]; row["productname"] = productNames[productindex]; row["price"] = price; row["quantity"] = quantity; row["total"] = price * quantity; var date = new Date(); date.setFullYear(2013, Math.floor(Math.random() * 11), Math.floor(Math.random() * 27)); date.setHours(0, 0, 0, 0); row["date"] = date; data[i] = row; } return data; } var saverenderer = function (rowid) { //id = $('#jqxgrid').jqxGrid('getrowid', rowid); rowdata = $('#jqxgrid').jqxGrid('getrowdata', rowid); caption = 'yes'; if(rowdata.save == 1) caption = 'no'; return '<div class="renderedgridcell" id="save_' + rowid + '">' + caption + '</div>'; } var theme = getDemoTheme(); // prepare the data var data = generatedata(200); var source = { localdata: data, datatype: "array", updaterow: function (rowid, rowdata, commit) { // synchronize with the server - send update command // call commit with parameter true if the synchronization with the server is successful // and with parameter false if the synchronization failder. //commit(true); if(!saveRows.in_array(rowid)) { saveRows.push(rowid); // Solution a) rowdata.save = 1; //Solution b) //rowdata.save = 1; //$('#jqxgrid').jqxGrid('updaterow', rowid, rowdata); //Solution c) //rowdata2 = $('#jqxgrid').jqxGrid('getrowdatabyid', rowid); //rowdata2.save = 1; //$('#jqxgrid').jqxGrid('updaterow', rowid, rowdata2); } }, datafields: [ { name: 'id', type: 'number' }, { name: 'save', type: 'number' }, { name: 'firstname', type: 'string' }, { name: 'lastname', type: 'string' }, { name: 'productname', type: 'string' }, { name: 'available', type: 'bool' }, { name: 'quantity', type: 'number' }, { name: 'price', type: 'number' }, { name: 'date', type: 'date' } ] }; var dataAdapter = new $.jqx.dataAdapter(source); // initialize jqxGrid $("#jqxgrid").jqxGrid( { width: 800, source: dataAdapter, editable: true, theme: theme, filterable: true, sortable: true, pageable: true, pagesize: 40, pagesizeoptions: ['10', '20', '30', '40', '50', '100'], selectionmode: 'multiplecellsadvanced', columns: [ { text: 'id', width: 40, datafield: 'id', pinned: true, editable: false }, { text: 'Is saved', datafield: 'save', cellsrenderer: saverenderer, editable: false, filterable: false, width: 80, pinned: true }, { text: 'First Name', columntype: 'textbox', datafield: 'firstname', width: 80 }, { text: 'Last Name', datafield: 'lastname', columntype: 'textbox', width: 80 }, { text: 'Product', columntype: 'dropdownlist', datafield: 'productname', width: 195 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', width: 67 }, { text: 'Ship Date', datafield: 'date', columntype: 'datetimeinput', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'd', validation: function (cell, value) { if (value == "") return true; var year = value.getFullYear(); if (year >= 2014) { return { result: false, message: "Ship Date should be before 1/1/2014" }; } return true; } }, { text: 'Quantity', datafield: 'quantity', width: 70, align: 'right', cellsalign: 'right', columntype: 'numberinput', validation: function (cell, value) { if (value < 0 || value > 150) { return { result: false, message: "Quantity should be in the 0-150 interval" }; } return true; }, createeditor: function (row, cellvalue, editor) { editor.jqxNumberInput({ decimalDigits: 0, digits: 3 }); } }, { text: 'Price', datafield: 'price', align: 'right', cellsalign: 'right', cellsformat: 'c2', columntype: 'numberinput', validation: function (cell, value) { if (value < 0 || value > 15) { return { result: false, message: "Price should be in the 0-15 interval" }; } return true; }, createeditor: function (row, cellvalue, editor) { editor.jqxNumberInput({ digits: 3 }); } } ] }); });
Kind Regards,
KlausHi Klaus,
Thanks for the provided code.
By calling “updaterow” method, the Grid will call the synchronization “updaterow” callback of the source object. However, as you do not confirm the UI changes as commit(true) is not called, the Grid will not be updated by your “updaterow” method call.
As a solution, you need to call “commit(true)” in the “updaterow” callback.
var batchUpdate = false; var source = { localdata: data, datatype: "array", updaterow: function (rowid, rowdata, commit) { // synchronize with the server - send update command // call commit with parameter true if the synchronization with the server is successful // and with parameter false if the synchronization failder. //commit(true); if (!saveRows.in_array(rowid)) { saveRows.push(rowid); // Solution a) rowdata.save = 1; //Solution b) //rowdata.save = 1; batchUpdate = true; $('#jqxgrid').jqxGrid('updaterow', rowid, rowdata); batchUpdate = false; //Solution c) //rowdata2 = $('#jqxgrid').jqxGrid('getrowdatabyid', rowid); //rowdata2.save = 1; //$('#jqxgrid').jqxGrid('updaterow', rowid, rowdata2); } if (batchUpdate) commit(true); },
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Hello Dimitar,
I copied your solution in my example and the behaviour has not changed. It works when there is no filter active, it does not work when there is a filter.
I have used console.log for further investigation:
Without filter, the updaterow callback is called, but it also works correctly if I just use Solution a) without commit(true)With a filter, the updaterow callback is not called as the line “$(‘#jqxgrid’).jqxGrid(‘updaterow’, rowid, rowdata);” returns false – if no filter is selected, it returns true.
So the reason must be the filter in my humble opinion. Could you please verify that?
updaterow: function (rowid, rowdata, commit) { // synchronize with the server - send update command // call commit with parameter true if the synchronization with the server is successful // and with parameter false if the synchronization failder. //commit(true); console.log("batchUpdate: " + batchUpdate) if (!saveRows.in_array(rowid)) { saveRows.push(rowid); // Solution a) rowdata.save = 1; //Solution b) //rowdata.save = 1; batchUpdate = true; value = $('#jqxgrid').jqxGrid('updaterow', rowid, rowdata); console.log("value: " + value) batchUpdate = false; //Solution c) //rowdata2 = $('#jqxgrid').jqxGrid('getrowdatabyid', rowid); //rowdata2.save = 1; //$('#jqxgrid').jqxGrid('updaterow', rowid, rowdata2); } if (batchUpdate) { console.log("commit") commit(true); } },
Without filter console says:
batchUpdate: false
batchUpdate: true
commit
value: trueWith filter console says:
batchUpdate: false
value: falseKind Regards,
KlausHello Klaus,
A working sample is provided below:
<!DOCTYPE html><html lang="en"><head> <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" /> <script type="text/javascript" src="../../scripts/jquery-1.8.3.min.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.edit.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.filter.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.pager.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.sort.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxdropdownlist.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcheckbox.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcalendar.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxnumberinput.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxdatetimeinput.js"></script> <script type="text/javascript" src="../../jqwidgets/globalization/globalize.js"></script> <script type="text/javascript" src="../../scripts/gettheme.js"></script> <script type="text/javascript" src="generatedata.js"></script> <script type="text/javascript"> $(document).ready(function () { var saveRows = new Array(); Array.prototype.in_array = function (needle) { for (var i = 0; i < this.length; i++) if (this[i] === needle) return true; return false; } function generatedata(rowscount, hasNullValues) { // prepare the data var data = new Array(); if (rowscount == undefined) rowscount = 100; var firstNames = [ "Andrew", "Nancy", "Shelley", "Regina", "Yoshi", "Antoni", "Mayumi", "Ian", "Peter", "Lars", "Petra", "Martin", "Sven", "Elio", "Beate", "Cheryl", "Michael", "Guylene" ]; var lastNames = [ "Fuller", "Davolio", "Burke", "Murphy", "Nagase", "Saavedra", "Ohno", "Devling", "Wilson", "Peterson", "Winkler", "Bein", "Petersen", "Rossi", "Vileid", "Saylor", "Bjorn", "Nodier" ]; var productNames = [ "Black Tea", "Green Tea", "Caffe Espresso", "Doubleshot Espresso", "Caffe Latte", "White Chocolate Mocha", "Caramel Latte", "Caffe Americano", "Cappuccino", "Espresso Truffle", "Espresso con Panna", "Peppermint Mocha Twist" ]; var priceValues = [ "2.25", "1.5", "3.0", "3.3", "4.5", "3.6", "3.8", "2.5", "5.0", "1.75", "3.25", "4.0" ]; for (var i = 0; i < rowscount; i++) { var row = {}; var productindex = Math.floor(Math.random() * productNames.length); var price = parseFloat(priceValues[productindex]); var quantity = 1 + Math.round(Math.random() * 10); row["id"] = i; row["available"] = productindex % 2 == 0; if (hasNullValues == true) { if (productindex % 2 != 0) { var random = Math.floor(Math.random() * rowscount); row["available"] = i % random == 0 ? null : false; } } row["save"] = 0; row["firstname"] = firstNames[Math.floor(Math.random() * firstNames.length)]; row["lastname"] = lastNames[Math.floor(Math.random() * lastNames.length)]; row["name"] = row["firstname"] + " " + row["lastname"]; row["productname"] = productNames[productindex]; row["price"] = price; row["quantity"] = quantity; row["total"] = price * quantity; var date = new Date(); date.setFullYear(2013, Math.floor(Math.random() * 11), Math.floor(Math.random() * 27)); date.setHours(0, 0, 0, 0); row["date"] = date; data[i] = row; } return data; } var saverenderer = function (rowid) { //id = $('#jqxgrid').jqxGrid('getrowid', rowid); rowdata = $('#jqxgrid').jqxGrid('getrowdata', rowid); caption = 'yes'; if (rowdata.save == 1) caption = 'no'; return '<div class="renderedgridcell" id="save_' + rowid + '">' + caption + '</div>'; } var theme = getDemoTheme(); // prepare the data var data = generatedata(200); var batchUpdate = false; var source = { localdata: data, datatype: "array", updaterow: function (rowid, rowdata, commit) { // synchronize with the server - send update command // call commit with parameter true if the synchronization with the server is successful // and with parameter false if the synchronization failder. //commit(true); if (!saveRows.in_array(rowid)) { saveRows.push(rowid); // Solution a) rowdata.save = 1; //Solution b) //rowdata.save = 1; batchUpdate = true; $('#jqxgrid').jqxGrid('updaterow', rowid, rowdata); batchUpdate = false; //Solution c) //rowdata2 = $('#jqxgrid').jqxGrid('getrowdatabyid', rowid); //rowdata2.save = 1; //$('#jqxgrid').jqxGrid('updaterow', rowid, rowdata2); } if (batchUpdate) commit(true); }, datafields: [ { name: 'id', type: 'number' }, { name: 'save', type: 'number' }, { name: 'firstname', type: 'string' }, { name: 'lastname', type: 'string' }, { name: 'productname', type: 'string' }, { name: 'available', type: 'bool' }, { name: 'quantity', type: 'number' }, { name: 'price', type: 'number' }, { name: 'date', type: 'date' } ] }; var dataAdapter = new $.jqx.dataAdapter(source); // initialize jqxGrid $("#jqxgrid").jqxGrid( { width: 800, source: dataAdapter, editable: true, theme: theme, filterable: true, sortable: true, pageable: true, pagesize: 40, pagesizeoptions: ['10', '20', '30', '40', '50', '100'], selectionmode: 'multiplecellsadvanced', columns: [ { text: 'id', width: 40, datafield: 'id', pinned: true, editable: false }, { text: 'Is saved', datafield: 'save', cellsrenderer: saverenderer, editable: false, filterable: false, width: 80, pinned: true }, { text: 'First Name', columntype: 'textbox', datafield: 'firstname', width: 80 }, { text: 'Last Name', datafield: 'lastname', columntype: 'textbox', width: 80 }, { text: 'Product', columntype: 'dropdownlist', datafield: 'productname', width: 195 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', width: 67 }, { text: 'Ship Date', datafield: 'date', columntype: 'datetimeinput', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'd', validation: function (cell, value) { if (value == "") return true; var year = value.getFullYear(); if (year >= 2014) { return { result: false, message: "Ship Date should be before 1/1/2014" }; } return true; } }, { text: 'Quantity', datafield: 'quantity', width: 70, align: 'right', cellsalign: 'right', columntype: 'numberinput', validation: function (cell, value) { if (value < 0 || value > 150) { return { result: false, message: "Quantity should be in the 0-150 interval" }; } return true; }, createeditor: function (row, cellvalue, editor) { editor.jqxNumberInput({ decimalDigits: 0, digits: 3 }); } }, { text: 'Price', datafield: 'price', align: 'right', cellsalign: 'right', cellsformat: 'c2', columntype: 'numberinput', validation: function (cell, value) { if (value < 0 || value > 15) { return { result: false, message: "Price should be in the 0-15 interval" }; } return true; }, createeditor: function (row, cellvalue, editor) { editor.jqxNumberInput({ digits: 3 }); } } ] }); }); </script></head><body class='default'> <div id='jqxWidget'> <div id="jqxgrid"></div> <div style="font-size: 12px; font-family: Verdana, Geneva, 'DejaVu Sans', sans-serif; margin-top: 30px;"> <div id="cellbegineditevent"></div> <div style="margin-top: 10px;" id="cellendeditevent"></div> </div> </div></body></html>
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Hello Dimitar,
unfortunately this is the same updaterow function you provided me earlier with and it is NOT working. It is doing just fine if there is no filter selected. But if there is no filter selected I do not need to call the updaterow function again.
Now if there is a filter active (like First Name starts with Pete), the manual change (like change the last name from Burke to Burke2) is displayed correctly. But contrary to the case with no filter, the Column “Is Saved” is not updated, the attribute save is not changed and the line $(‘#jqxgrid’).jqxGrid(‘updaterow’, rowid, rowdata); returns false – keep in mind that this call is not even necessary when there is no filter active. Why does the behaviour change, if the only difference is a filter beeing active or not. There has to be a bug.
Try it, look at the output of console.log with a filter on and with all filters cleared:
<!DOCTYPE html><html lang="en"><head> <link rel="stylesheet" href="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/styles/jqx.base.css" type="text/css" /> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/scripts/jquery-1.8.3.min.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxcore.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxdata.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxbuttons.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxscrollbar.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxmenu.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxgrid.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxgrid.edit.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxgrid.selection.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxgrid.filter.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxgrid.pager.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxgrid.sort.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxlistbox.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxdropdownlist.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxcheckbox.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxcalendar.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxnumberinput.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/jqxdatetimeinput.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/jqwidgets/globalization/globalize.js"></script> <script type="text/javascript" src="http://www.jqwidgets.com/jquery-widgets-demo/scripts/gettheme.js"></script> <!--<script type="text/javascript" src="generatedata.js"></script>--> <script type="text/javascript"> $(document).ready(function () { var saveRows = new Array(); Array.prototype.in_array = function (needle) { for (var i = 0; i < this.length; i++) if (this[i] === needle) return true; return false; } function generatedata(rowscount, hasNullValues) { // prepare the data var data = new Array(); if (rowscount == undefined) rowscount = 100; var firstNames = [ "Andrew", "Nancy", "Shelley", "Regina", "Yoshi", "Antoni", "Mayumi", "Ian", "Peter", "Lars", "Petra", "Martin", "Sven", "Elio", "Beate", "Cheryl", "Michael", "Guylene" ]; var lastNames = [ "Fuller", "Davolio", "Burke", "Murphy", "Nagase", "Saavedra", "Ohno", "Devling", "Wilson", "Peterson", "Winkler", "Bein", "Petersen", "Rossi", "Vileid", "Saylor", "Bjorn", "Nodier" ]; var productNames = [ "Black Tea", "Green Tea", "Caffe Espresso", "Doubleshot Espresso", "Caffe Latte", "White Chocolate Mocha", "Caramel Latte", "Caffe Americano", "Cappuccino", "Espresso Truffle", "Espresso con Panna", "Peppermint Mocha Twist" ]; var priceValues = [ "2.25", "1.5", "3.0", "3.3", "4.5", "3.6", "3.8", "2.5", "5.0", "1.75", "3.25", "4.0" ]; for (var i = 0; i < rowscount; i++) { var row = {}; var productindex = Math.floor(Math.random() * productNames.length); var price = parseFloat(priceValues[productindex]); var quantity = 1 + Math.round(Math.random() * 10); row["id"] = i; row["available"] = productindex % 2 == 0; if (hasNullValues == true) { if (productindex % 2 != 0) { var random = Math.floor(Math.random() * rowscount); row["available"] = i % random == 0 ? null : false; } } row["save"] = 0; row["firstname"] = firstNames[Math.floor(Math.random() * firstNames.length)]; row["lastname"] = lastNames[Math.floor(Math.random() * lastNames.length)]; row["name"] = row["firstname"] + " " + row["lastname"]; row["productname"] = productNames[productindex]; row["price"] = price; row["quantity"] = quantity; row["total"] = price * quantity; var date = new Date(); date.setFullYear(2013, Math.floor(Math.random() * 11), Math.floor(Math.random() * 27)); date.setHours(0, 0, 0, 0); row["date"] = date; data[i] = row; } return data; } var saverenderer = function (rowid) { //id = $('#jqxgrid').jqxGrid('getrowid', rowid); rowdata = $('#jqxgrid').jqxGrid('getrowdata', rowid); caption = 'yes'; if (rowdata.save == 1) caption = 'no'; return '<div class="renderedgridcell" id="save_' + rowid + '">' + caption + '</div>'; } var theme = getDemoTheme(); // prepare the data var data = generatedata(200); var batchUpdate = false; var source = { localdata: data, datatype: "array", updaterow: function (rowid, rowdata, commit) { // synchronize with the server - send update command // call commit with parameter true if the synchronization with the server is successful // and with parameter false if the synchronization failder. //commit(true); console.log("batchUpdate: " + batchUpdate) if (!saveRows.in_array(rowid)) { saveRows.push(rowid); // Solution a) rowdata.save = 1; //Solution b) //rowdata.save = 1; batchUpdate = true; value = $('#jqxgrid').jqxGrid('updaterow', rowid, rowdata); console.log("value: " + value) batchUpdate = false; //Solution c) //rowdata2 = $('#jqxgrid').jqxGrid('getrowdatabyid', rowid); //rowdata2.save = 1; //$('#jqxgrid').jqxGrid('updaterow', rowid, rowdata2); } if (batchUpdate) { console.log("commit") commit(true); } }, datafields: [ { name: 'id', type: 'number' }, { name: 'save', type: 'number' }, { name: 'firstname', type: 'string' }, { name: 'lastname', type: 'string' }, { name: 'productname', type: 'string' }, { name: 'available', type: 'bool' }, { name: 'quantity', type: 'number' }, { name: 'price', type: 'number' }, { name: 'date', type: 'date' } ] }; var dataAdapter = new $.jqx.dataAdapter(source); // initialize jqxGrid $("#jqxgrid").jqxGrid( { width: 800, source: dataAdapter, editable: true, theme: theme, filterable: true, sortable: true, pageable: true, pagesize: 40, pagesizeoptions: ['10', '20', '30', '40', '50', '100'], selectionmode: 'multiplecellsadvanced', columns: [ { text: 'id', width: 40, datafield: 'id', pinned: true, editable: false }, { text: 'Is saved', datafield: 'save', cellsrenderer: saverenderer, editable: false, filterable: false, width: 80, pinned: true }, { text: 'First Name', columntype: 'textbox', datafield: 'firstname', width: 80 }, { text: 'Last Name', datafield: 'lastname', columntype: 'textbox', width: 80 }, { text: 'Product', columntype: 'dropdownlist', datafield: 'productname', width: 195 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', width: 67 }, { text: 'Ship Date', datafield: 'date', columntype: 'datetimeinput', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'd', validation: function (cell, value) { if (value == "") return true; var year = value.getFullYear(); if (year >= 2014) { return { result: false, message: "Ship Date should be before 1/1/2014" }; } return true; } }, { text: 'Quantity', datafield: 'quantity', width: 70, align: 'right', cellsalign: 'right', columntype: 'numberinput', validation: function (cell, value) { if (value < 0 || value > 150) { return { result: false, message: "Quantity should be in the 0-150 interval" }; } return true; }, createeditor: function (row, cellvalue, editor) { editor.jqxNumberInput({ decimalDigits: 0, digits: 3 }); } }, { text: 'Price', datafield: 'price', align: 'right', cellsalign: 'right', cellsformat: 'c2', columntype: 'numberinput', validation: function (cell, value) { if (value < 0 || value > 15) { return { result: false, message: "Price should be in the 0-15 interval" }; } return true; }, createeditor: function (row, cellvalue, editor) { editor.jqxNumberInput({ digits: 3 }); } } ] }); }); </script></head><body class='default'> <div id='jqxWidget'> <div id="jqxgrid"></div> <div style="font-size: 12px; font-family: Verdana, Geneva, 'DejaVu Sans', sans-serif; margin-top: 30px;"> <div id="cellbegineditevent"></div> <div style="margin-top: 10px;" id="cellendeditevent"></div> </div> </div></body></html>
Kind Regards,
KlausWell, I figured out the problem and it goes back to my first post. When data is filtered (e.g. Firstname starts with Pete) the rowid param in the first call of the updaterow function is null again. I don’t know why, because after the first test with version 2.8.1 earlier today, that issue seemed fixed. Now the error occurs again, and as you can see, I am using your online version of the js files, which are 2.8.1
So if no filter is set, the “rowdata.saved = 1;” alone is enough to change the data and trigger the cells rendering (probably because rowid is correct).
If a filter is set, I need the code:
rowid = rowdata.idif (!saveRows.in_array(rowid)) { saveRows.push(rowid); // Solution a) rowdata.save = 1; //Solution b) //rowdata.save = 1; batchUpdate = true; console.log(rowid) value = $('#jqxgrid').jqxGrid('updaterow', rowid, rowdata); console.log("value: " + value) batchUpdate = false; //Solution c) //rowdata2 = $('#jqxgrid').jqxGrid('getrowdatabyid', rowid); //rowdata2.save = 1; //$('#jqxgrid').jqxGrid('updaterow', rowid, rowdata2);}if (batchUpdate){ console.log("commit") commit(true);}
for it to work, that means initializing the rowid variable AND manually execute the updaterow method. Could you please check into this and see why I get the rowid as null (and maybe you not?) and check against the online version of your 2.8.1 as referenced in my example in the last post?
Kind Regards,
KlausHi Klaus,
By default, it is wrong to update the row’s data by using a code like: rowdata.save = 1. For updating values, “setcellvalue” or “updaterow” methods in jqxGrid should be used. The “rowid” on my side is passed correctly even after filtering, sorting or other operation. I will continue testing and if I find out something, I will update the post.
Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Hello Dimitar,
I tested the behaviour with rowid is null on two browsers before I made the posting yesterday. Now I do not have this behaviour anymore, neither in my localversion of jqwidgets nor in the online one.
Thank you for your suggestion with setcellvalue and updaterow. I have updated my function and that seems to work (after switching from selectionmode multiplecellsadvanced to singlerow to get the rowindex for the updaterow method – but that will be my mode in the final version, so that’s quite alright).
updaterow: function (rowid, rowdata, commit) { if (!saveRows.in_array(rowid)) { saveRows.push(rowid); rowindex = $('#jqxgrid').jqxGrid('getselectedrowindex'); $("#jqxgrid").jqxGrid('setcellvalue', rowindex, "save", 1); newdata = $('#jqxgrid').jqxGrid('getrowdatabyid', rowid); batchUpdate = true value = $('#jqxgrid').jqxGrid('updaterow', rowid, newdata); batchUpdate = false; } if (batchUpdate) commit(true);},
So, I am still a little bit buffled why I did not get a rowid in my last test yesterday but now I am happy. Thank you very much for your patience and suggestions.
Kind Regards,
KlausI am currently using version 3.0.4 of jQWidgets. I have a similar problem as the one described here. I am using the grid with filtering enabled and also one column with checkboxes set as editable.
Changing the state of a checkbox works fine as long as no filters are applied. I am listening on the ‘cellendedit’ event to hook in some state tracking logic of my own, unrelated to the grid. The problem is that the ‘event’ variable passed to the callback function listening to the ‘cellendedit’ event is supposed to have a property called ‘rowindex’, which it does and it has the correct value, but only if filtering is not active. Once filterings is activated, this ‘rowindex’ property always has ‘undefined’ as its value, no matter which row has been edited.
This is only half of the problem. The other half is that the checkboxes disappear from all the rows when the ‘rowindex’ is undefined.
I would really appreciate your help!
Kind regards
-
AuthorPosts
You must be logged in to reply to this topic.