What is the right way to set a two level igHierarchicalGrid for batch updating and get its aggregated transactions in the client?
In the attached example (inspired on some code found in this forum) the grid let the user to add, modify and delete rows from level 1 (categories) and level 2 (products). For simplicity in this example I am not catching deleted rows. The problem is that I can't get transactions from level 2. Also, in order to add rows at level 2 AutoCommit must be set to true (when parent row is new) , this is an issue because a) I cant use aggregated transactions (according to documentation: This option takes effect only when autoCommit is set to false), that means bigger packets sent to the server, b) italics applied to edited rows are lost so user can't see what has been edited. Is there a way to fix this?
Hello Luis,
The transactions for the child bands can be accessing through each respective child layout. For instance, to get the current transactions of the first child grid, something similar to the following may be used:
$($("#MyGrid").igHierarchicalGrid("allChildren")[0]).igGrid("allTransactions")
In order to retain aggregate transactions and respectively, disabled AutoCommit on the root layout, I would suggest handling the rowAdded event and invoking commit manually:
//Bind after initialization $(document).delegate("#MyGrid", "iggridupdatingrowadded", function (evt, ui) {
$("#MyGrid").igGrid("commit"); });
Hope this helps. Please feel free to contact me if you have any questions.
Hi Petar, thank you for your help. Now I am able to get child transactions. I did other testing to see what happens:
var hierarchicalGridChildren = $("#MyGrid").igHierarchicalGrid("allChildren");
var transLevel4 = hierarchicalGridChildren.igGrid("transactionsAsString"); var transLevel3 = JSON.stringify(hierarchicalGridChildren.igGrid("pendingTransactions")); var transLevel2 = JSON.stringify(hierarchicalGridChildren.igGrid("allTransactions")); var transLevel1 = JSON.stringify($("#MyGrid").igGrid("allTransactions"));
I modified rowId 1, added rowId 5, and deleted rowId 4. Look the result of this at the image below (debug).
As you can see transLevel4 and transLevel2 have the same result (in this case transLevel4 and transLevel3 has nothing to do with the real level in the grid, it is just a name). Now I realize why transLevel3 is empty: there are no pending transactions because I am using AutoCommit(true). transLevel1 is empty because I didn't edit any parent row. Another interesting thing is that using stringify or transactionsAsString has the same effect. (Question 1) Does transactionsAsString use stringify behind the scene?
Regarding to iggridupdatingrowadded I have an issue: setting AutoCommit(false), new child rows are lost after pressing enter on the new row.
(Question 2) How to fix that?
And one more thing. I realized that new child rows inherit the parent's Id if the parent is not new, but when you add a new parent their children don't inherit the parent's Id. (Question 3) How to get the parent's Id and set the child's foreignkey?
Please guys I need to get this fixed before next monday :( Question 3 is the most important to me. I have tried many things. This is what I have till now:
$(document).delegate("#MyGrid", "iggridupdatinggenerateprimarykeyvalue", function (evt, ui) { pk = pk - 1; ui.value = pk; });
$(document).delegate("#MyGrid", "iggridupdatingrowadded", function (evt, ui) {
// getting the parent grid row data var parentRow = $(ui.owner.element).parents("tr[data-container='true']").prev("tr"); var parentRowId = $(parentRow).attr("data-id"); if (parentRowId == undefined) return;
var parentRowGrid = $(parentRow).closest("table"); var parentKey = $(parentRowGrid).igGrid("getCellValue", parseInt(parentRowId), "Id");
// doesn't work //ui.values["CategoryId"] = parentKey;
// doesn't work //var dataRecord = $("#MyGrid").igGrid("findRecordByKey", ui.rowID); //dataRecord.CategoryId = parentKey;
// doesn't work //var childGrids = $("#MyGrid").igHierarchicalGrid("allChildren"); //var dataRecord = $(childGrids).igGrid("findRecordByKey", ui.rowID); //dataRecord.CategoryId = parentKey;
/* with this (last two line of code) I receive the CategoryId but when parsing it in the server there is an error:'System.Runtime.Serialization.SerializationException' I think it is because transactions are not aggregated (because of AutoCommit(true), and because AgreggateTransactions(true) and because if I don't use AutoCommit(true) then new children on new parents can't be added... it is a chain of issues :(
This is what the server receive:
transactionsLevel1:[{"type":"newrow","tid":"c055","row":{"Id":-1,"Name":"AAA","Description":"AAA"},"rowId":-1}]transactionsLevel2:[{"type":"newrow","tid":"99b5","row":{"Id":-2,"Name":"BBBBB","CategoryId":null},"rowId":-2},{"type":"cell","rowId":-1,"tid":"a635","col":"CategoryId","value":-1}]
As you see there are two transactions for the rowId:-2, one when row is added and another when CategoryId is updated. */
var childGrids = $("#MyGrid").igHierarchicalGrid("allChildren"); $(childGrids[0]).igGridUpdating("setCellValue", ui.rowID, "CategoryId", parentKey);
});
Please Petar, do not leave me alone! Be a good guy and help me :)
Well, I found the best solution till now: make your own aggregated transaction log :) When I finish it I would like to share it here.
To answer your questions:
- Yes, transactionsAsString basically calls JSON.stringify before returning the transaction log.
- I think the reason is that the event handler posted by Petar is meant to work on a flat grid. In the hierachical scenario to commit the changes coming from the grid that has thrown the "rowAdded" event you need to do something like this:
$(document).delegate("#grid1", "iggridupdatingrowadded", function (evt, ui) { ui.owner.grid.commit();});
The difference from Petar's sample code is that he is using a selector that returns the parent table and calls commit on it. My sample uses the event args to get a reference to the grid that has a row added and call commit on it directly. Due to the event bubbling the "rowAdded" of each child grid will get captured by a handler attached to the parent one.
- As for the third question, I managed to reproduce what you reported and I am currently doing some further research on what's causing the foreignKeys to not get populated for child rows created for a new parent row. I should be able to provide you with a workaround for the issue a bit later today.
Best regards,
Stamen Stoychev
Thank you so much Stamen! I'll be waiting anxiously for your answer. ;)
Hi Stamen,
I have a hierarchical grid where I am facing issue for adding rows to child grid with existing rows. I tried your js that you recommended above. Its does insert the foreign key in ui.values,but when the transactions are posted, I dont see it. The "_addrow" function in infragistics.core.js is being hit before "iggridupdatingrowadding" function. So your js is not changing the actual transaction log due to which the inserted foreign key is not posted in transactions. Please advice.
Fantastic!!! that is a good new. Thank you so much for listening to customers :)
I am glad I was able to help! We are also determined to get this implemented in the code so you don't need to have some records in the children data sources to enable foreign key resolution. I have logged this as a work item in our internal tracking system with a Development ID of 185386. A support case is created on your behalf with number CAS-146925-F2J0Z4 , so that you can be notified when it is resolved.You can find your active cases under Account - Support Activity in our website. Select your ticket and go to Development Issues tab.
Once you get the service release containing the fix you will no longer need this workaround.
Thank you for using Infragistics forums!
THANK YOU SO MUCH! :)
It just works beautifully!!! I hope you add this functionality out of the box, this is very important when you are doing batch updating. Fortunately I am using negative numbers for primary and foreign keys for new rows in the grid, so that makes things simpler. In the server I change those negative numbers for real keys (actually the database does it). Thank you good man :)
The reason the foreign key is not automatically set for this case is that the data source of the child grid contains no records initially. Updating can only check for the foreign key within the records it sees and at the moment there is no communication built-in for the feature to ask parents for this information. We'll discuss internally whether or not such functionality should be implemented so we can cover the use-case. If such decision is made I'll create an internal work item and link it to the case created for this forums post. In this way you'll get notified once the implementation is available.
In the meantime you can use the workaround I've prepared. The idea behind it is to use the id of the child grid to extract the foreign key from it. It's not the cleanest solution but it's the shortest one by far, any other requiring traversing the hierarchical structure and identifying whose child the grid throwing the event is. The extracted key is then added to the row object "rowAdding" passes as an event argument. To keep the event binding consistent with your other code it would look something like this:
$(document).delegate("#grid1", "iggridupdatingrowadding", function (evt, ui) { var id = ui.owner.grid.id(), match = id.match(/_([-0-9]*)_/), fk = match && match.length === 2 ? parseInt(match[1], 10) : null; if (fk !== null && ui.owner.grid.options.foreignKey) { ui.values[ui.owner.grid.options.foreignKey] = fk; } });
Please, have in mind that the regex used may need to be modified if you are using anything other than numbers (positive or negative) as PKs. You'll have to ensure it works properly for your hierarchical grid.
I am attaching my sample for reference. I hope this helps! Please, let me know if you have any other questions and/or concerns!