jQWidgets Forums
Forum Replies Created
-
Author
-
April 25, 2013 at 12:59 pm in reply to: Changing id field – different rowid in updaterow and deleterow Changing id field – different rowid in updaterow and deleterow #20010
Addition:
My workaround doesn’t work, the getrowdata object has the correct id in it according to my console.log representation of the rowdata. But when I store the id column in a new variable, it also gets the old negative value (var myid = myrowdata.myid). I have tested this behaviour in two browsers.I don’t know why, but now that solution works again, however the rowid in the deleterow call still has the old negative id.
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,
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,
KlausHello 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,
KlausHello 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 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,
KlausHello 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,
KlausHello,
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.
April 11, 2013 at 4:30 pm in reply to: Get the row index via the row id Get the row index via the row id #19083I guess I have a solution, I remove all filters and use the getrows method to iterate over the rows and compare with getrowid if that entry is in my array. That is quite faster than I thought. Then I can retrieve the data, send my request and update an indicator in the row that the row was saved (before it was flagged as is not saved).
I used the updaterow function, but that somehow did not refresh my indicator field via the cellrenderer (the old value was still set). So I ended up deleting the row and adding it again. It ended up at the same position, so that was fine. I guess that was due to the fact that the id is a number and the initial sort is on the key. Is there any way I can give a position for the addrow function just to be sure?
I also tried applying a manual filter on my indicator and only getting those rows. That worked, but the deleterow always returned false for no apparent reason. But as I said the other solution works.
-
AuthorPosts