Hi
I am trying to get my first MVC website (and first use of jQuery) up and running with the Ignite grid. I have read many articles and posts but am now stuck with my batch updates.
With reference to this guide:
http://help.infragistics.com/NetAdvantage/jquery/Current/CLR4.0?page=Using_Events_in_NetAdvantage_for_jQuery.html
and the "Batch Updates" part.
I have a grid in my MVC view which uses UpdateURL to save its data. The view includes code to generate a temporary PrimaryKey (as described in the "Adding a PrimaryKey for the AddNewRow" section of the same article) for the new row and when the Save button is clicked the UpdateURL is followed to my controller to carry out the update.
The bit that stumps me is that the various Infragistics articles have a similar technique to get the temporary id in the view but this obviously cannot be the ID that is eventually created by the controller (since, in my case, it is a self incrementing IDENTITY column in SQL SERVER and is only defined when the record is INSERTed into the DB) so the view cannot be in charge of which IDs are used.
The controller can easily save the new record, which is then automatically assigned the new ID (I am using Entity Framework for this bit) but how do I get the new ID back to the grid from UpdatingSaveChanges so that when the user decides to delete the record they just saved the controller is presented with the new ID instead of the temporary one?
For me, it goes bang every time because my temporary IDs are negative and the real IDs are positive so the controller will never find the temporary ID in the DB.
I have tried setting the rowID and LookupCodeID in UpdatingSaveChanges but the values don't get back to the grid.
I am sure that I am missing something elementary because web development is all new to me and would appreciate some help.
View code:
@using (Html.BeginForm()) { <script type="text/javascript" > $.ig.loader(function () { var lookupCodeID_forNewRow = -1; // event raised after edit cell started $("#LUCGrid").live("iggridupdatinggenerateprimarykeyvalue", function (event, ui) { ui.value = lookupCodeID_forNewRow--; }); $("#LUCGrid").live("iggridupdatingeditcellstarted", function (event, ui) { if (!ui.editor) { return; } if (ui.key === 'LookupCodeID') { ui.editor.igEditor('option', 'readOnly', true); } }); $("#LUCGrid").live("iggridupdatingdatadirty", function (event, ui) { $("#LUCGrid").igGrid("commit"); return false; }); $("#LUCGrid").live("iggridupdatingrowadding", function (event, ui) { ui.values["LookupTypeID"] = (@Model.LookupTypeID); }); }); </script> <fieldset> <div class="LookupCodeTable" > @Html.ValidationSummary(true) @(Html.Infragistics() .Grid(Model.LookupCodes.AsQueryable()) .ID("LUCGrid") .Height("500px") .Width("500px") .PrimaryKey("LookupCodeID") .AutoCommit(false) .AutoGenerateColumns(false) .AutoGenerateLayouts(true) .Columns(column => { column.For(x => x.LookupCodeID).DataType("numeric"); column.For(x => x.Code).HeaderText("Code"); column.For(x => x.Description).HeaderText("Description"); }) .Features(features => { features.Sorting().Type(OpType.Remote); features.Paging().DefaultDropDownWidth("90px").PageSize(10).Type(OpType.Remote); features.Filtering().Type(OpType.Remote); features.Hiding().ColumnSettings(settings => { settings.ColumnSetting().ColumnKey("LookupCodeID").Hidden(false).AllowHiding(false); }); features.Updating() .ShowReadonlyEditors(false) .EditMode(GridEditMode.Row) .ColumnSettings(settings => { settings.ColumnSetting().ColumnKey("LookupCodeID") .EditorType(ColumnEditorType.Text) .Required(true) .ReadOnly(true) .Validation(true); settings.ColumnSetting().ColumnKey("Code") .EditorType(ColumnEditorType.Text) .Required(true) .Validation(true); settings.ColumnSetting().ColumnKey("Description") .EditorType(ColumnEditorType.Text) .Required(true) .Validation(true); }) .AddRowTooltip(string.Format("Click this row to add new {0} code", Model.ShortDescription)) .AddRowLabel(string.Format("Add new {0} code", Model.ShortDescription)); }) .UpdateUrl(Url.Action("UpdatingSaveChanges")) .DataSourceUrl(Url.Action(CodesController.GRID_GetLookupCodesForType, new { inlookupTypeID = Model.LookupTypeID })) .Render() ) </div> <p> <input type="button" id="saveChanges" value="Save" /> </p> </fieldset> <script type="text/javascript" src="../../Scripts/LookupCodes.js"> </script>
Controller code:
public ActionResult UpdatingSaveChanges() { ViewData["GenerateCompactJSONResponse"] = false; GridModel m = new GridModel(); List<Transaction<wsLookupCode>> transactions = m.LoadTransactions<wsLookupCode>(HttpContext.Request.Form["ig_transactions"]); string strResult = string.Empty; foreach (Transaction<wsLookupCode> oTx in transactions) { if (clsiGridHelper.GetTransactionType(oTx.type) == clsiGridHelper.TransactionRowType.New) { LookupCode oLUC = new LookupCode(); oLUC.Code = clsStringHelper.GetString(oTx.row.Code); oLUC.DefaultValue = clsStringHelper.GetString(oTx.row.DefaultValue); oLUC.Description = clsStringHelper.GetString(oTx.row.Description); oLUC.LookupTypeID = oTx.row.LookupTypeID; LUCRepository.Add(oLUC); strResult = UoW.Save(); if (strResult.Length == 0) { oTx.row.LookupCodeID = oLUC.LookupCodeID; oTx.rowId = oTx.row.LookupCodeID.ToString(); } } else if (clsiGridHelper.GetTransactionType(oTx.type) == clsiGridHelper.TransactionRowType.Deleted) { LookupCode oLUC = LUCRepository.GetByID(Convert.ToInt64(oTx.rowId)); if (oLUC != null & !oLUC.IsDeleted) { oLUC.IsDeleted = true; }// got LUC?? } else if (clsiGridHelper.GetTransactionType(oTx.type) == clsiGridHelper.TransactionRowType.Row) { LookupCode oLUC = LUCRepository.GetByID(oTx.row.LookupCodeID); if (oLUC != null) { if (oTx.row.Code != null && oLUC.Code != oTx.row.Code) { oLUC.Code = oTx.row.Code; } if (oTx.row.Description != null && oLUC.Description != oTx.row.Description) { oLUC.Description = oTx.row.Description; } if (oTx.row.DefaultValue != null && oLUC.DefaultValue != oTx.row.DefaultValue) { oLUC.DefaultValue = oTx.row.DefaultValue; } }// got LUC?? }// row type }// each transaction strResult = UoW.Save(); JsonResult result = new JsonResult(); Dictionary<string, bool> response = new Dictionary<string, bool>(); if (strResult.Length == 0) { response.Add("Success", true); } else { response.Add(strResult, false); } result.Data = response; return result; }// UpdatingSaveChanges
Hello Graeme,
You have two choices to deal with this:
1.Rebind the grid
2.Implement your own logic to handle the newly assigned ids from the database.
As the first choice is very straightforward to implement I'll explain how to proceed with the second approach.
On the server you have to serialize the newly assigned id's with the response.
Here is the an example code:
public ActionResult SaveProducts()
{
GridModel m = new GridModel();
List<Transaction<Product>> transactions = m.LoadTransactions<Product>(HttpContext.Request.Form["ig_transactions"]);
List<Ids> ids = new List<Ids>();
int newId = 0;
foreach (Transaction<Product> t in transactions)
if (t.type == "newrow")
// repository Add mehtod returns the new id generated from the underlying data source
newId = productsRepository.Add(t.row);
ids.Add(new Ids() { OldId = t.row.ProductID, NewId = newId });
}
JsonResult result = new JsonResult();
Dictionary<string, object> response = new Dictionary<string, object>();
response.Add("Success", true);
response.Add("ids", ids);
result.Data = response;
return result;
On the client you have to process the response and update the data source with the new IDs. Handling the response from the server currently is achieved with an internal method igDataSource._addChangesSuccessHandler, but we will expose a public API for this.
Here is an example code:
$.ig.loader(function () {
$("#grid1").data("igGrid").dataSource._addChangesSuccessHandler(function (data) {
var i;
for (i = 0; i < data.ids.length; i++) {
$("#grid1").igGridUpdating("setCellValue", data.ids[i].OldId, "ProductID", data.ids[i].NewId); // Line 5
$("#grid1 > tbody > tr[data-id='" + data.ids[i].OldId + "']").attr("data-id", data.ids[i].NewId); // Line 6
$("#grid1").data("igGrid").dataSource.commit(); // Line 8
$("#grid1").data("igGrid").dataSource.allTransactions().length = 0; // Line 9
});
In line 5 of the code I'm using the igGridUpdating.setCellValue API to update the old row Id with the new Id. However there is some additional work which is not done by the API. For example the data-id attribute of the row has to be updated manually. This attribute holds the id of the row in the DOM.
In line 8 and line 9 I'm clearing the transaction log which is not needed for the purposes of updating the Ids.
Attached you can find a complete sample.
Hope this helps, Martin Pavlov Infragistics, Inc.
Hi Martin
Your solution works very well, thanks for your help.
I used m.DataBind() in my controller first but that resorts the grid so I now use your alternative which works great for me.
Graeme
We are glad you are able to move forward with your application. If you have any questions, please do not hesitate to let us know.