Friday, April 09, 2010

Post form field value on jqGrid load/Save

Lately i started to work with jqGrid, I was surprised with the flexibility of the grid. In my project I have a dropdown control list all the countries and i want the Grid to load the saved states in this country also to save any new added state under the selected country, although this requirement looks easy but it’s not straight forward to accomplish it using controls outside the grid. Here is initial grid code:

   1: $(document).ready(function() {
   2:     jQuery("#StatesGrid").jqGrid({
   3:         url: '/Admin/LoadStates/' + $('#Countries  option:selected').val(),
   4:         datatype: 'json',
   5:         mtype: 'GET',
   6:         colNames: ['StateID', 'State', 'Phone Code'],
   7:         colModel: [
   8:               { name: 'StateId', index: 'StateId', width: 200, align: 'left', editable: true, editrules: { edithidden: false }, hidden: true },
   9:               { name: 'StateName', index: 'StateName', width: 200, align: 'left', editable: true, edittype: 'text', editoptions: { size: 30, maxlength: 50 }, editrules: { required: true }, search: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
  10:               { name: 'PhoneCode', index: 'PhoneCode', width: 200, align: 'left', editable: true, edittype: 'text', editoptions: { size: 30, maxlength: 50 }, editrules: { required: true }, search: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
  11:               ],
  12:         editurl: "/Admin/SaveStates/",
  13:         //direction: 'rtl',
  14:         pager: jQuery('#Statespager'),
  15:         rowNum: 10,
  16:         rowList: [10, 20, 50],
  17:         sortname: 'StateId',
  18:         sortorder: "ASC",
  19:         viewrecords: true,
  20:         toolbar: true,
  21:         imgpath: '/Content/themes/ui-lightness/images',
  22:         caption: 'States',
  23:         subGrid: false,
  24:         height: 250
  25:     }).navGrid('#Statespager', { search: true, edit: true, add: true, del: false },
  26:     { closeAfterAdd: true, closeAfterEdit: true, recreateForm: false }, //edit
  27:     {closeAfterAdd: true, closeAfterEdit: true, recreateForm: false }, //add
  28:         {}, //Delete
  29:         {closeOnEscape: true, multipleSearch: true, closeAfterSearch: true, recreateForm: false, groupOps: [{ op: "AND", text: "All"}]} //search
  30:         );
  31: });

Loading States data:

The first option i thought about to load the data was to change the grid “url” attribute like this:

   1: $('#Countries').change(function() {
   2:         jQuery("#statesGrid").setGridParam({ url: '/Admin/LoadStates/' + $('#Countries  option:selected').val() }).trigger("reloadGrid");
   3:     });

this will concatenate the selected country ID to the grid url then reload the grid using the new url.

I discovered later that the ID could be passed to the controller action method using the “postData” attribute like this:

   1: postData : { countryId : $('#Countries  option:selected').val()} ,
   2:  

but still need to reload the Grid on countries dropdown change as shown before using “.trigger("reloadGrid")”.

On the server side the controller action method only need to change the parameter name from “id” in the "url" method to “countryId” as defined in the postData array.

 

Saving new states data:

Now let’s say we need we want to add new state, the first thing came in my mind is to pass the country id in the grid “editurl” attribute. but sadly it didn’t work as the grid pass the id value “_empty” and i wasn’t able to change the parameter name.

I was also hoping i could get the countryId from the postData but sadly jqGrid don’t post it on saving.

the only workaround i found was to add new column in the grid column model, this column is hidden with “custom” edit type and configured as follow:     

   1: { name: 'CountryId', index: 'CountryId', width: 200, hidden: true, editable: true, 
   2:     edittype: 'custom', 
   3:     editrules: { edithidden: true, required: true }, 
   4:     editoptions: { custom_element: myelem, custom_value: function(elem) { return $('#Countries  option:selected').val(); } } },
   5:  

Then implement the myelem function:

   1: function myelem(value, options) {
   2:             var el = document.createElement("input");
   3:             el.type = "hidden";
   4:             el.value = value;
   5:             return el;
   6:         }

Although i didn’t use the hidden field added in myelem function but it didn’t work without it.

No comments: