I want to add a Duplicate Row functionality to my igGrid. That means, I want to append a new row by copying an existing row. After appending this row, the requirement is to keep it uncommited. But when I click on this new row, I get "recordOrPropertyNotFoundException" error. What is the best way to do this? I have a button column. I use MVC wrapper for the grid. Row editing is enabled on the grid.
GridColumn DuplicateRow = new GridColumn(); DuplicateRow.Key = "DuplicateRow"; DuplicateRow.HeaderText = ""; DuplicateRow.DataType = "string"; DuplicateRow.Template = "<input type='button' title='Duplicate Row' onclick='duplicateRow(${TemplateID})' value='D' class=btn--primary' style='padding: 0.2rem'/>';
Please see my code below.
function duplicateRow(rowId) { var currentRow = $('#Grid1').data('igGrid').dataSource.findRecordByKey(rowId); var newRow = $.extend(true, {}, currentRow); newRow.TemplateID = generateID(25); $('#Grid1').igGridUpdating("addRow", newRow); $('#Grid1').igGridUpdating("startEdit", newRow.TemplateID, 1); $('#Grid1').igGridUpdating("endEdit", true); }
function generateID(length) { let text = "" const possible = "0123456789" for (let i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)) } return text }
And I don't see Done / Cancel buttons after programmatically start editing on this new row. Please help me to find a solution to this issue.
Hello Bijumon,
I am glad I was able to help.
Feel free to contact me if you have any additional questions regarding this matter.
Hi, Thank you for responding to my issue. I found the reason for the "recordOrPropertyNotFoundException" error. The data type of my ID column (TemplateID) is "number", but the function generateID() was returning a text ID. After I cast this text ID to number using parseInt, it started working. Your reply helped me to cancel the event using event.stopPropagation(). The edit mode of my grid was already "Row". After adding the new row by copying old row, the old row used to be in Edit mode, which is not the desired functionality. I want the new row to be in Edit mode. After adding event.stopPropagation(), I am able to achieve the desired functionality. Please see the working code below.
function duplicateRow(rowId) { var currentRow = $('#Grid1').data('igGrid').dataSource.findRecordByKey(rowId); var newRow = $.extend(true, {}, currentRow); newRow.TemplateID = generateID(7); $('#Grid1').igGridUpdating("addRow", newRow); $('#Grid1').igGridUpdating("startEdit", newRow.TemplateID, 1); event.stopPropagation(); }
function generateID(length) { let text = "" const possible = "0123456789" for (let i = 0; i < length; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)) } return parseInt(text) }
Again, thank you very much for your response.
Thank you for posting in our forum.
I believe you get this message because you have forgotten to stop the event propagation, causing the cell with the button to try to enter edit mode.
I see you generate some random ID for the row you are about to add, which is necessary for the grid to function correctly. The missing “Done” and “Cancel” buttons could be caused by not setting the editMode to “row” and setting is to “cell” instead, so please check to make sure.
Here is a code sample that you could check for a reference. My primary keys are numbers - that is why I am just increasing them by 1 when adding every new record.
<!DOCTYPE html> <html> <head> <title>Sample</title> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="http://code.jquery.com/ui/1.10.0/jquery-ui.js"></script> <script src="http://cdn-na.infragistics.com/igniteui/2018.1/latest/js/infragistics.loader.js"></script> </head> <body> <table id="grid"></table> <script> function duplicateRow(elem){ //without stopping the event propagation the cell with the button would enter "Edit" mode, causing an error event.stopPropagation(); let rowId = $("#grid").igGrid("getElementInfo", $(elem).closest("td")).rowId let rec = $("#grid").igGrid("findRecordByKey", rowId) //since a record with the same Primary key already exists, we have to generate a new unique one for the duplicate record let data = $("#grid").data("igGrid").dataSource.data() //getting the biggest ProductID number let biggestID = Math.max.apply(Math, data.map(function(record){return record.ProductID;})) //creating a new unique ProductID for the new record rec.ProductID = biggestID + 1 //adding the new record $("#grid").igGridUpdating("addRow", rec); } $.ig.loader({ scriptPath: "http://cdn-na.infragistics.com/igniteui/2018.1/latest/js/", cssPath: "http://cdn-na.infragistics.com/igniteui/2018.1/latest/css/", resources: "igGrid.*", ready: function () { let ds = [ { "ProductID": 1, "ExpiryDate": 'December 17, 2018 03:24:00', "ProductName": "Chai", "CategoryName": "Beverages", "InStock": 39 }, { "ProductID": 2, "ExpiryDate": 'November 15, 2018 03:24:00', "ProductName": "Chang", "CategoryName": "Beverages", "InStock": 17 }, { "ProductID": 3, "ExpiryDate": 'April 14, 2018 03:24:00', "ProductName": "Aniseed Syrup", "CategoryName": "Condiments", "InStock": 13 }, { "ProductID": 4, "ExpiryDate": 'April 15, 2018 03:24:00', "ProductName": "Chef Anton\u0027s Cajun Seasoning", "CategoryName": "Condiments", "InStock": 53 }, { "ProductID": 5, "ExpiryDate": 'Febriary 27, 2018 03:24:00', "ProductName": "Chef Anton\u0027s Gumbo Mix", "CategoryName": "Condiments", "InStock": 0 }, { "ProductID": 6, "ExpiryDate": 'October 10, 2018 03:24:00', "ProductName": "Grandma\u0027s Boysenberry Spread", "CategoryName": "Condiments", "InStock": 120 }, { "ProductID": 7, "ExpiryDate": 'June 12, 2018 03:24:00', "ProductName": "Uncle Bob\u0027s Organic Dried Pears", "CategoryName": "Produce", "InStock": 15 }, { "ProductID": 8, "ExpiryDate": 'May 21, 2018 03:24:00', "ProductName": "Northwoods Cranberry Sauce", "CategoryName": "Condiments", "InStock": 6 }, { "ProductID": 9, "ExpiryDate": 'May 16, 2018 03:24:00', "ProductName": "Mishi Kobe Niku", "CategoryName": "Meat/Poultry", "InStock": 29 } ] $("#grid").igGrid({ dataSource: ds, responseDataKey: "results", autoCommmit: false, primaryKey: "ProductID", width: '100%', columns: [ { headerText: "Product ID", key: "ProductID", dataType: "number", width: "15%", hidden: true}, { headerText: "Duplicate Row", key: "Abc", unbound: true, template: "<input type='button' title='Duplicate Row' onclick='duplicateRow(this)' value='D' class=btn--primary' style='padding: 0.2rem'/>"}, { headerText: "Product Name", key: "ProductName", dataType: "string", width: "20%"}, { headerText: "Expiry Date", key: "ExpiryDate", dataType: "date", width: "20%"}, { headerText: "Category", key: "CategoryName", dataType: "string", width: "20%"}, { headerText: "Units In Stock", key: "InStock", dataType: "number", width: "20%"}, ], features: [ { name: "Updating", } ] }) } }) </script> </body> </html>
If you need any additional assistance, feel free to contact me.