jqgrid不正确在编辑框中选择下拉选项值

我正在使用表单编辑。 表单中有两个选择框。 一个选择框是国家,另一个选择框是国家。 状态选择框取决于所选的国家,并且将被动态地填充。 例如:

国家:

美国(期权价值= 1)
英国(期权价值= 2)

对美国国家:

阿拉巴马州(选项值= 1)
加州(选项值= 2)
佛罗里达(选项值= 3)
夏威夷(选项值= 4)

英国州:

伦敦(期权价值= 5)
牛津(期权价值= 6)

正如你在上面看到的,英国国家的id从5开始。当我编辑包含Country id=2 (UK)State id=6 (Oxford) ,编辑表格将正确显示 – 国家是英国和州是牛津。 但是,如果您下拉状态选择框的选项文本是正确的(它显示伦敦牛津),但期权价值将从0开始。应该正确的是,选项值应该从5开始。

如果您选择国家下拉框并将其更改为美国,然后再次更改为英国,则选项值将填充正确(从5开始)。

我的问题是,当编辑表单加载时,我们如何使用基于编辑框中的国家的正确选项值填充状态的选择框?

您的问题的答案取决于您在收到有关“美国的州”和“英国的州”下显示的信息的来源。 jqGrid支持两种可能性:1)editoptions的value参数的使用 2) buildSelect选项的dataUrlbuildSelect参数的使用。 第一种方法是在本地编辑的情况下最好的方法,或者如果可能的选项列表是静态的。 第二种选择将用于这种情况,即从数据库中获得关于某个国家的州,国家和州的信息。 我将描述使用value参数的例子的解决方案,使其对服务器组件没有依赖关系。 在使用dataUrlbuildSelect情况下,实现上的大部分是相同的。

我做了一个实例来说明你需要什么。

主要的问题是editoptionsvalue在初始化时只能使用一次 。 在dataInit函数里面可以覆盖这个value ,但是在国家的第一个选择/下拉框中改变value之后,第二个带有状态的选择/下拉框必须手动重建。 要做到这一点,人们必须明白,所选的HTML元素具有从行ID“_”和列名:rowId +“_State”构造的id。 此外,重要的是, editoptionsvalue必须重置为初始值,以便任何状态id都可以解码为状态名称。

以下是示例中的代码:

 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(); } }); 

更新 :我更新了上面的代码,以使其与表单编辑的情况下工作。 你可以在这里看到它。 因为jqGrid不支持本地编辑表单编辑我无法测试代码。 不过,我希望我能够充分利用所需的变化。

更新2 :我扩展了上面的代码来支持

  1. 内联编辑,表单编辑,搜索工具栏和高级搜索
  2. 编辑表单中的上一个或下一个导航按钮
  3. 在选择中改进键盘支持(在某些浏览器中刷新相关选择的问题已得到解决)

演示的新版本在这里 。 演示的修改代码如下:

 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"}); 

更新3 :演示代码的最后一个版本,你会在这里找到。

我正在使用表单编辑。 表单中有三个选择框。 一个选择框是国家,一个选择框是城市,另一个选择框是街道。 城市选择框取决于所选的国家,并将动态填充。 街道选择框取决于所选的城市,并且将被动态地填充。 我在MySQL中保存国家,城市,街道。 如果我选择国家,如何从MySQL表中转换城市选择框