I would like to display a dialog with some igEditors in it when the user is editing a row in a igGrid instead of using the default mode that is provided with the grid. Is there a way to override that event or wire up a jquery function to display a dialog when the grid row enters edit mode. Currently I use an action link (from post https://es.infragistics.com/community/forums/f/ignite-ui-for-javascript/58692/links-inside-a-grid) in the grid rows to send them to another view and then when they are done editing the data and it is saved they are redirected back to the main page. I am new to both MVC and jquery so any code samples/examples would be much appreciated.Thank you in advanceMVC 3, C# Razor
Hi jagwynn,
I wrote example for you which supresses default functionality of grid-updating to start row-editing and instead shows dialog (startEditDialog ) which contains fields for desired columns. Those fields are initialized with values of cells located in row. On OK button, values from dialog-fields are used to update row in grid.
If igGrid is created by javascript application, then it is easier to use member-event-option editRowStarting. If igGrid is created by Mvc application, then you should use "live" feature of jquery. In this case you will not need codes related to create grid: - variables gridData, colors, names - statement $("#grid1").igGrid({...}); - <table id=grid1></table>
For simplicity processing, that sample uses ids of dialog-fields on base of column-keys of grid. Also editors in that example are plain INPUTs, so, they set string values to modified cells. If application uses other data types, then special editors (like igDateEditor, igNumericEditor, etc), can be used, or application may to convert specific values to desired type within "set" (click event of dialogOK).Please read comments in javascript below.
<head>//application should have <link>s for css and <script>s for jquery and infragistics files <script type="text/javascript"> // Reference to event arguments used to start editing. // It is also used as container of grid-column-keys. // That allows to simplify logic used on end editing. var gridUpdating, // reference to edit-dialog editDialog, // data source of grid gridData = [], i = -1, colors = ['Red', 'Orange', 'Pink', 'Yellow', 'Green'], names = ['Jet', 'Train', 'Car', 'Boat']; // create data for grid while (i++ < 10) { gridData[i] = { 'ProductID': i, 'Name': names[i % 4], 'Color': colors[i % 5], 'ListPrice': Math.pow((6 - i % 4), 7) * 1.25 + i }; }
$(function () { // create grid $("#grid1").igGrid({ autoGenerateColumns: true, defaultColumnWidth: '150px', features: [ { /* // example to process event which is raised before start-edit-row // when igGrid is created by javascript, rather than Mvc helper editRowStarting: function (evt, ui) { // open dialog with fields startEditDialog(ui); // cancel default editing return false; }, */ name: 'Updating' } ], dataSource: gridData });
// process event which is raised before start-edit-row (for Mvc) $("#grid1").live("iggridupdatingeditrowstarting", function (evt, ui) { // open dialog with fields startEditDialog(ui); // cancel default editing return false; });
// process OK button and update grid with data from dialog $('#dialogOK').click(function () { // keys of grid-columns var keys = gridUpdating.keys, len = keys.length, // new values values = []; // fill values from dialog-editors while (len-- > 0) { values[keys[len]] = $('#' + keys[len] + 'Editor').val(); } // update row in grid gridUpdating.owner.updateRow(gridUpdating.rowID, values); // close dialog editDialog.dialog('close'); });
$('#dialogCancel').click(function () { editDialog.dialog('close'); }); });
function startEditDialog (ui) { var key, val, i = -1, // columns in grid columns = ui.owner.grid.options.columns, len = columns.length; // show which row is currently editing $('#rowID').html('Edit Row #' + ui.rowID); // save reference to arguments used by this event (for easier processing end editing) gridUpdating = ui; // optional old values in case application will need to verify new value on end editing ui.oldValues = {}; // column keys (used to simplify end editing) ui.keys = []; // loop through all columns of grid and initialize editors while (++i < len) { // grid-column key key = columns[i].key; // save column key ui.keys.push(key); // get value of cell in row at column val = ui.owner.grid.getCellValue(ui.rowID, key); //or //val = ui.owner._getVal(ui.rowID, key); // save old value ui.oldValues[key] = val; // initialize edit-field with cell value // note: for simplicity, the ids of edit-fields match with name-of-column+"Editor" $('#' + key + 'Editor').val(val); } if (!editDialog) { // create dialog editDialog = $('#editDialog').dialog(); } // show dialog editDialog.dialog('open'); } </script></head>
<body> <table id="grid1"></table> <div id="editDialog" title="Grid Row Editor" style="display:none"> <span id="rowID" style="background: #E0E0E0;"></span><br /> ProductID: <input id="ProductIDEditor" /><br /> Name: <input id="NameEditor" /><br /> Color: <input id="ColorEditor" /><br /> ListPrice: <input id="ListPriceEditor" /><br /><br /> <input id="dialogOK" type="button" value="OK" /> <input id="dialogCancel" type="button" value="Cancel" /> </div></body>
Normal 0 false false false EN-US X-NONE X-NONE
Thank you for the sample that was exactly what I was looking to do.
One problem that I am running into using it is that once the dialog is closed and the “savechanges” method is called for the grid the only data that is posted back to the controller is “"[{\"type\":\"row\",\"tid\":\"60d0\",\"row\":[],\"rowId\":585655}]"”
If I am not using the dialog then the correct data is posted back to controller:
"[{\"type\":\"row\",\"tid\":\"8a63\",\"row\":{\"NASNUMBER\":null,\"StoreName\":null,\"DateCalled\":null,\"ServiceTech\":null,\"PONumber\":null,\"Problem\":null,\"DispatchFor\":null,\"Completed\":true,\"DateCompleted\":null},\"rowId\":\"583149\"}]"
Any suggestions on how I can process it on the dialog to get the complete data passed back?
The code that I am using below:
View:
<script type="text/javascript">
var gridUpdating, editDialog;
$(function ()
{
$("#igGrid1").live("iggridupdatingeditrowstarting", function (evt, ui)
startEditDialog(ui);
return false;
});
$('#dialogOK').click(function ()
// keys of grid-columns
var keys = gridUpdating.keys,
len = keys.length,
// new values
values = [];
// fill values from dialog-editors
while (len-- > 0) {
values[keys[len]] = $('#' + keys[len] + 'Editor').val();
}
// update row in grid
gridUpdating.owner.updateRow(gridUpdating.rowID, values);
// close dialog
$("#igGrid1").igGrid("saveChanges");
editDialog.dialog('close');
$('#dialogCancel').click(function ()
function startEditDialog(ui)
var key, val, i = -1,
// columns in grid
columns = ui.owner.grid.options.columns,
len = columns.length;
// show which row is currently editing
$('#rowID').html('Edit Row #' + ui.rowID);
// save reference to arguments used by this event (for easier processing end editing)
gridUpdating = ui;
// optional old values in case application will need to verify new value on end editing
ui.oldValues = {};
// column keys (used to simplify end editing)
ui.keys = [];
// loop through all columns of grid and initialize editors
while (++i < len)
// grid-column key
key = columns[i].key;
// save column key
ui.keys.push(key);
// get value of cell in row at column
val = ui.owner.grid.getCellValue(ui.rowID, key);
//or
//val = ui.owner._getVal(ui.rowID, key);
// save old value
ui.oldValues[key] = val;
// initialize edit-field with cell value
// note: for simplicity, the ids of edit-fields match with name-of-column+"Editor"
$('#' + key + 'Editor').val(val);
if (!editDialog)
// create dialog
editDialog = $('#editDialog').dialog();
// show dialog
editDialog.dialog('open');
</script>
<body>
<div id="editDialog" title="Service Call Editor" style="display:none">
PO Number: <label id="PONumberEditor" /><br />
NasNumber: <input id="NASNUMBEREditor" /><br />
Store Name: <input id="StoreNameEditor" /><br />
Service Tech: <input id="ServiceTechEditor" /><br />
Dipatched For: <input id="DispatchForEditor" /><br /><br />
Completed: <input id="CompletedEditor" /><br /><br />
SignedBy: <input id="SignedByEditor" /><br /><br />
<input id="dialogOK" type="button" value="OK" />
<input id="dialogCancel" type="button" value="Cancel" />
</div>
</body>
<p>
@( Html.Infragistics().Grid<vLyonsServiceCall>()
.ID("igGrid1")
.AutoCommit(false)
.UpdateUrl("EditingCalls")
.PrimaryKey("PONumber")
.Columns(column =>
column.For(x => x.NASNUMBER).DataType("string").HeaderText("R-Number");
column.For(x => x.StoreName).DataType("string").HeaderText("Name");
column.For(x => x.DateCalled).DataType("date").HeaderText("Call Date");
column.For(x => x.Completed).DataType("bool").HeaderText("Completed");
column.For(x => x.DateCompleted).DataType("date").HeaderText("DateCompleted");
column.For(x => x.ServiceTech).DataType("string").HeaderText("Service Tech");
column.For(x => x.PONumber).DataType("number").HeaderText("Po Number");
column.For(x => x.Problem).DataType("string").HeaderText("Problem");
column.For(x => x.DispatchFor).DataType("string").HeaderText("Dispatched For");
column.For(x => x.SignedBy).DataType("string").HeaderText("SignedBy");
})
.Features(features =>
features.GroupBy().ColumnSettings(groupedGolumn =>
groupedGolumn.ColumnSetting().ColumnKey("Name").IsGroupBy(true);
features.Paging().PageSize(100).PrevPageLabelText("Previous").NextPageLabelText("NEXT");
features.Sorting().Mode(SortingMode.Single).ColumnSettings(settings =>
settings.ColumnSetting().ColumnKey("Name").AllowSorting(true);
features.Selection().MouseDragSelect(true).MultipleSelection(true).Mode(SelectionMode.Row);
features.Filtering().Mode(FilterMode.Advanced);
features.Updating().EnableAddRow(false).EnableDeleteRow(false).StartEditTriggers(GridStartEditTriggers.DblClick);
.ClientDataSourceType(ClientDataSourceType.JSON)
.DataSourceUrl(Url.Action("TestEditCalls"))
.Width("100%")
.Height("650")
.LocalSchemaTransform(true)
.DataBind()
.Render()
)
</p>
Controller:
[GridDataSourceAction]
public ActionResult EditingCalls(string ig_transactions)
ArrayList transactions = (ArrayList)Procurios.Public.JSON.JsonDecode(ig_transactions);
var ctx = new NGBDataEntities();
var ds = ctx.vLyonsServiceCalls;
ViewData["GenerateCompactJSONResponse"] = false;
GridModel m = new GridModel();
foreach (Hashtable t in transactions)
DO SOMETHING….
ctx.SaveChanges();
return RedirectToAction("Lyons", ds);
There are 2 problems in you codes.Grid uses primary key and your dialog has LABEL with key for that column instead of INPUT. It means that LABEL.val(value) will fails, because LABEL does not support val(value). In this case theLABEL.html(value) should be used.
Same for get val() for primary key. The var value=LABEL.html() should be used. If your application uses numeric value for primary key, then that should be converted to number, likevar value = parseInt(LABEL.val(), 10).
I suggest you to treat LABEL differently. To set value, you may use something likeif (key === 'PONumber') { $('#' + key + 'Editor').html(val);} else { $('#' + key + 'Editor').val(val);}
However, it is not related to problem with saveChanges.
When grid uses saveChanges with primary key, then transaction(s) should have have correct primary key member within transaction.
You may do that by one of the following:
1. Hard coded preset value of primary key $('#dialogOK').click(function () { ... values = { PONumber: gridUpdating.rowID }; while (len-- > 0) { if (keys[len] !== 'PONumber') { values[keys[len]] = $('#' + keys[len] + 'Editor').val(); } } ... });
2. Pass all original values, so, primary key column will be included automatically and server will see all row-values.$('#dialogOK').click(function () { ... values = gridUpdating.oldValues; while (len-- > 0) { if (keys[len] !== 'PONumber') { values[keys[len]] = $('#' + keys[len] + 'Editor').val(); } } ...});
Also, as I mentioned in first post,values[keys[len]] = $('#' + keys[len] + 'Editor').val();will set values as strings. If particular column is not string, then application should convert it to correct type.For example, if column NASNUMBER expects integer and editor is plain INPUT, then it is better to do something like below
$('#dialogOK').click(function () { ... values = gridUpdating.oldValues; while (len-- > 0) { if (keys[len] !== 'PONumber') { values[keys[len]] = $('#' + keys[len] + 'Editor').val(); } else if (keys[len] === 'NASNUMBER') { values[keys[len]] = parseInt($('#' + keys[len] + 'Editor').val(), 10); } } ...});
Similar should be done for all other columns with not string data types.
Thank you worked like a charm. Thanks again for putting me on the right track.