The answer to your question depends a little on the source where you get information about what is displayed in the "State for the USA" and "State for the UK" sections. There are two possibilities supported by jqGrid: 1) using the value editoptions parameter 2) using dataUrl and buildSelect parameter. The first method is the best in case of local editing or if the list of possible parameters is static. The second option will be used when information on the states, countries and states of a country will be obtained at the request of AJAX from the database. I describe the solution using the value parameter as an example so as not to depend on server components. Most parts of the implementation are the same when using dataUrl and buildSelect .
I made a live example that shows what you need.
The main problem is that value editoptions used only once at the time of initialization. Inside the dataInit function, you can overwrite value , but after changing the value in the first selection / drop-down list box with countries, the second selection / drop-down list box with states must be rebuilt manually. To do this, you need to understand that the HTML select element has an id built from the id '_' row and a column name: rowId + "_State". In addition, it is important that the value editoptions must be reset to the initial value, so that any status identifier can be decoded into the status name.
Here is the code from the example :
var countries = { '1': 'US', '2': 'UK' }; var states = { '1': 'Alabama', '2': 'California', '3': 'Florida', '4': 'Hawaii', '5': 'London', '6': 'Oxford' }; var statesOfCountry = { 1: { '1': 'Alabama', '2': 'California', '3': 'Florida', '4': 'Hawaii' }, 2: { '5': 'London', '6': 'Oxford' } }; var mydata = [ { id: '0', Country: '1', State: '1', Name: "Louise Fletcher" }, { id: '1', Country: '1', State: '3', Name: "Jim Morrison" }, { id: '2', Country: '2', State: '5', Name: "Sherlock Holmes" }, { id: '3', Country: '2', State: '6', Name: "Oscar Wilde" } ]; var lastSel = -1; var grid = jQuery("#list"); var resetStatesValues = function () { grid.setColProp('State', { editoptions: { value: states} }); }; grid.jqGrid({ data: mydata, datatype: 'local', colModel: [ { name: 'Name', width: 200 }, { name: 'Country', width: 100, editable: true, formatter: 'select', edittype: 'select', editoptions: { value: countries, dataInit: function (elem) { var v = $(elem).val(); // to have short list of options which corresponds to the country // from the row we have to change temporary the column property grid.setColProp('State', { editoptions: { value: statesOfCountry[v]} }); }, dataEvents: [ { type: 'change', fn: function(e) { // To be able to save the results of the current selection // the value of the column property must contain at least // the current selected 'State'. So we have to reset // the column property to the following //grid.setColProp('State', { editoptions:{value: statesOfCountry[v]} }); //grid.setColProp('State', { editoptions: { value: states} }); resetStatesValues(); // build 'State' options based on the selected 'Country' value var v = parseInt($(e.target).val(), 10); var sc = statesOfCountry[v]; var newOptions = ''; for (var stateId in sc) { if (sc.hasOwnProperty(stateId)) { newOptions += '<option role="option" value="' + stateId + '">' + states[stateId] + '</option>'; } } // populate the new if ($(e.target).is('.FormElement')) { // form editing var form = $(e.target).closest('form.FormGrid'); $("select#State.FormElement", form[0]).html(newOptions); } else { // inline editing var row = $(e.target).closest('tr.jqgrow'); var rowId = row.attr('id'); $("select#" + rowId + "_State", row[0]).html(newOptions); } } } ] } }, { name: 'State', width: 100, editable: true, formatter: 'select', edittype: 'select', editoptions: { value: states } } ], onSelectRow: function (id) { if (id && id !== lastSel) { if (lastSel != -1) { resetStatesValues(); grid.restoreRow(lastSel); } lastSel = id; } }, ondblClickRow: function (id, ri, ci) { if (id && id !== lastSel) { grid.restoreRow(lastSel); lastSel = id; } resetStatesValues(); grid.editRow(id, true, null, null, 'clientArray', null, function (rowid, response) { // aftersavefunc grid.setColProp('State', { editoptions: { value: states} }); }); return; }, editurl: 'clientArray', sortname: 'Name', height: '100%', viewrecords: true, rownumbers: true, sortorder: "desc", pager: '#pager', caption: "Demonstrate dependend select/dropdown lists (edit on double-click)" }).jqGrid('navGrid','#pager', { edit: true, add: true, del: false, search: false, refresh: false }, { // edit options recreateForm:true, onClose:function() { resetStatesValues(); } }, { // add options recreateForm:true, onClose:function() { resetStatesValues(); } });
UPDATED . I updated the code above to make it work when editing a form. You can see it live here . Since jqGrid does not support local editing to edit the form, I could not test the code. Nevertheless, I hope that I have made all the necessary changes.
UPDATED 2 . I have extended the above code to support
- Built-in editing, form editing, search toolbar and advanced search
- Previous or next navigation buttons on the edit form
- Improved keyboard support for selections (issue with updating dependent selections in some browsers fixed)
The new version of the demo is here . The modified demo code, which you will find below:
var countries = { '1': 'US', '2': 'UK' }, //allCountries = {'': 'All', '1': 'US', '2': 'UK'}, // we use string form of allCountries to have control on the order of items allCountries = ':All;1:US;2:UK', states = { '1': 'Alabama', '2': 'California', '3': 'Florida', '4': 'Hawaii', '5': 'London', '6': 'Oxford' }, allStates = ':All;1:Alabama;2:California;3:Florida;4:Hawaii;5:London;6:Oxford', statesOfUS = { '1': 'Alabama', '2': 'California', '3': 'Florida', '4': 'Hawaii' }, statesOfUK = { '5': 'London', '6': 'Oxford' }, // the next maps contries by ids to states statesOfCountry = { '': states, '1': statesOfUS, '2': statesOfUK }, mydata = [ { id: '0', country: '1', state: '1', name: "Louise Fletcher" }, { id: '1', country: '1', state: '3', name: "Jim Morrison" }, { id: '2', country: '2', state: '5', name: "Sherlock Holmes" }, { id: '3', country: '2', state: '6', name: "Oscar Wilde" } ], lastSel = -1, grid = $("#list"), removeAllOption = function (elem) { if (typeof elem === "object" && typeof elem.id === "string" && elem.id.substr(0, 3) !== "gs_") { // in the searching bar $(elem).find('option[value=""]').remove(); } }, resetStatesValues = function () { // set 'value' property of the editoptions to initial state grid.jqGrid('setColProp', 'state', { editoptions: { value: states} }); }, setStateValues = function (countryId) { // to have short list of options which corresponds to the country // from the row we have to change temporary the column property grid.jqGrid('setColProp', 'state', { editoptions: { value: statesOfCountry[countryId]} }); }, changeStateSelect = function (countryId, countryElem) { // build 'state' options based on the selected 'country' value var stateId, stateSelect, parentWidth, $row, $countryElem = $(countryElem), sc = statesOfCountry[countryId], isInSearchToolbar = $countryElem.parent().parent().parent().hasClass('ui-search-toolbar'), //$(countryElem).parent().parent().hasClass('ui-th-column') newOptions = isInSearchToolbar ? '<option value="">All</option>' : ''; for (stateId in sc) { if (sc.hasOwnProperty(stateId)) { newOptions += '<option role="option" value="' + stateId + '">' + states[stateId] + '</option>'; } } setStateValues(countryId); // populate the subset of contries if (isInSearchToolbar) { // searching toolbar $row = $countryElem.closest('tr.ui-search-toolbar'); stateSelect = $row.find(">th.ui-th-column select#gs_state"); parentWidth = stateSelect.parent().width(); stateSelect.html(newOptions).css({width: parentWidth}); } else if ($countryElem.is('.FormElement')) { // form editing $countryElem.closest('form.FormGrid').find("select#state.FormElement").html(newOptions); } else { // inline editing $row = $countryElem.closest('tr.jqgrow'); $("select#" + $.jgrid.jqID($row.attr('id')) + "_state").html(newOptions); } }, editGridRowOptions = { recreateForm: true, onclickPgButtons: function (whichButton, $form, rowid) { var $row = $('#' + $.jgrid.jqID(rowid)), countryId; if (whichButton === 'next') { $row = $row.next(); } else if (whichButton === 'prev') { $row = $row.prev(); } if ($row.length > 0) { countryId = grid.jqGrid('getCell', $row.attr('id'), 'country'); changeStateSelect(countryId, $("#country")[0]); } }, onClose: function () { resetStatesValues(); } }; grid.jqGrid({ data: mydata, datatype: 'local', colModel: [ { name: 'name', width: 200, editable: true }, { name: 'country', width: 100, editable: true, formatter: 'select', stype: 'select', edittype: 'select', searchoptions: { value: allCountries, dataInit: function (elem) { removeAllOption(elem); }, dataEvents: [ { type: 'change', fn: function (e) { changeStateSelect($(e.target).val(), e.target); } }, { type: 'keyup', fn: function (e) { $(e.target).trigger('change'); } } ] }, editoptions: { value: countries, dataInit: function (elem) { setStateValues($(elem).val()); }, dataEvents: [ { type: 'change', fn: function (e) { changeStateSelect($(e.target).val(), e.target); } }, { type: 'keyup', fn: function (e) { $(e.target).trigger('change'); } } ] }}, { name: 'state', width: 100, formatter: 'select', stype: 'select', editable: true, edittype: 'select', editoptions: { value: states }, searchoptions: { value: allStates, dataInit: function (elem) { removeAllOption(elem); } } } ], onSelectRow: function (id) { if (id && id !== lastSel) { if (lastSel !== -1) { $(this).jqGrid('restoreRow', lastSel); resetStatesValues(); } lastSel = id; } }, ondblClickRow: function (id) { if (id && id !== lastSel) { $(this).jqGrid('restoreRow', lastSel); lastSel = id; } resetStatesValues(); $(this).jqGrid('editRow', id, { keys: true, aftersavefunc: function () { resetStatesValues(); }, afterrestorefunc: function () { resetStatesValues(); } }); return; }, editurl: 'clientArray', sortname: 'name', ignoreCase: true, height: '100%', viewrecords: true, rownumbers: true, sortorder: "desc", pager: '#pager', caption: "Demonstrate dependend select/dropdown lists (inline editing on double-click)" }); grid.jqGrid('navGrid', '#pager', { del: false }, editGridRowOptions, editGridRowOptions); grid.jqGrid('filterToolbar', {stringResult: true, searchOnEnter: true, defaultSearch : "cn"});
UPDATED 3 . You can find the latest demo code here .