I will consider the question of inline editing and adding a new row in jqGrid, as applicable to ASP.NET MVC 3 and Razor C #. I will also include the C # controller code to populate the grid and save the data in the grid. First, let's see how to install jqGrid 4.4.1 in an MVC3 web application using the NuGet package manager.
- Install jQuery 1.7.2 or higher.
- Install jQuery.UI.Combined.
- Install jqGrid 4.4.1
You can download jqGrid separately from
http://www.trirand.com/blog/?page_id=6
and jqGrid documentation can be found in
http://www.trirand.com/jqgridwiki/doku.php
I will not test the code in this post, but it is based on code that really works. I am going to use brute force approach to solve the complex and complex problem of populating jqGrid from an action method, editing a single row or adding a new editable row, and then saving the row in the action method. I am sure that more optimal ways to do this can be found, but this is a good starting point. I'm not going to show you how to customize the look of your jqGrid, I will leave it to you. I will use JSON as the data exchange format between jqGrid and ASP.NET MVC 3. I am not going to add the problem of deleting a row in the grid.
Let's start with the GET action method in the controller
public JsonResult GetProduct(int productId = 0) { var productsQuery = dbContext.FirstOrDefault(p => p.ProductId == productId); var productsList = new List<Products>(); // SQL does not understand ToString() so we have to do this or something like it foreach(var p in productsQuery) { var product = new Product{ ProductId = p.ProductId, Product.Name = p.Name, Product.Date = p.Date.ToShortDateString() // and so on... }; productsList.Add(product); } // You must build an anonymous object that can then be converted into a 2-dimensional // array formatted for jqGrid, convert it to a 2d array then Json. Note that all grid // data must be in string format. var jsonData = new { total = 1, page = 1, records = productsQuery.Count(), rows = productsList.Select(p => new { id = p.id.ToString(), cell = new string[] { p.Name, p.Date.ToShortDateString(), // and so on... } }).ToArray(); }; return Json(jsonData, JsonRequestBehavior.AllowGet); }
And viewing ...
<script type="text/javascript"> $(document).ready(function () { var lastSelectedId; var grid = $('#grid'); grid.jqGrid({ url: "@Url.Action("GetProducts", "Products")", datatype: 'json', mtype: 'post', colNames: ['ProductId', 'Name', 'Date', // and so on... ], colModel: [ { name: 'ProductId', index: 'ProductId', editable: false }, { name: 'Name', index: 'Name', editable: true, edittype: 'text' }, { name: 'Date', index: 'Date', editable: true, edittype: 'text' } // and so on... ], onSelectRow: function(rowid) { if (rowid && rowid !== lastSelectedId) { grid.jqGrid('resotreRow', lastSelectedId); lastSelectedId = rowid; } grid.jqGrid('editRow', rowid, { keys: true }); }, editurl: "@Url.Action("SaveProducts", "Products"); rownum: [10], rowList: [5,10,20,50], pager: '#grid_pager', sortName: 'Name', viewrecords: true, gridview: true, caption: 'Sample Grid' }); grid.jqGrid('navGrid', '#pager', { edit: false, add: false: del: false, refresh: false }); grid.jqGrid('inlineNav', '#pager', { addParams: { position: 'first', addRowParams: { keys: true, oneditfunc: onInlineEdit } add: true, edit: false, save: false, cancel: true }); function onInlineEdit(rowid) { // add inline editing functionality here } </script> @using (Html.BeginForm("","", FormMethod.Post, new { id = "ProductsForm" })) { <table id="grid"> </table> <div id="pager"> </div> }
and then the POST method
[HttpPost] public JsonResult SaveProduct(FormCollection frm) { Product product; if (frm["oper"] == "add") { product = new Product(); } else { int productId = Int32.Parse(frm["id"]); product = dbContext.Products.FirstOrDefault(p => p.ProductId == productId); } foreach (var key in frmAllKeys) { switch(key) { case "Name": product.Name = frm[key]; break; case "Date": product.Date = DateTime.Parse(frm[key]); break; // and so on... } } try { if (frm["oper"] == "add") { dbContext.AddObject(product); } dbContext.SaveChanges(); } catch (Exception ex) { Debug.WriteLine(exception.StackTrace); return Json(false); } return Json(true); }
There are better ways to do this, but this is a good start. I do not consider a problem with a dynamic network. I do not know how to do this. Suffice it to say that dynamic jqGrid will require a lot more JavaScript and / or C # code. I would like to take a look at the "grid in grid" functionality in jqGrid to combine a static grid with a dynamic grid.
I tried to create functionality that would take an object type, a list of records, and generate jqGrid Array and Json data for the mesh without having to do all the extra work shown above. I think this can be done with reflection, but I don’t have time to do it right now.
Finally, I also tried to create functionality that would retrieve data from FormCollection and populate the object specified only for the object type and FormCollection. Again, I think this can be done with reflection, but I don’t have time to do it right now. If someone wants to try creating a JQGrid Json MVC3 CQ generator and extractor, I would recommend using the Entity Framework Code First method with the POCO classes for your model. POCO classes are much easier to work with object objects for such a task.
Hope this helps :)