jqgrid错误选择编辑框中的下拉选项值

发布于 2021-02-02 17:25:00

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

国家:

美国(选项值= 1)
英国(选项值= 2)

美国的州:

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

英国的州:

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

如您所见,英国的国家ID以5开头。当我编辑包含Country id=2 (UK)和的记录时State id=6 (Oxford),编辑表单将正确显示-
国家为英国,国家为牛津。但是,如果您下拉状态选择框,则选项文本正确(显示伦敦牛津),但选项值将从0开始。正确的是,选项值应从5开始。

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

我的问题是,当加载编辑表单时,如何根据编辑框中的国家/地区为状态选择框填充正确的选项值?

关注者
0
被浏览
62
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    您问题的答案在一定程度上取决于来源,您可以从中获得“美国国家”和“英国国家”下显示的信息。的是由支持的jqGrid两种可能性:1)的使用value的参数editoptions
    2)的使用dataUrlbuildSelect参数的editoptions。在本地编辑或可能选项列表为静态的情况下,第一种方法是最好的方法。在以下情况下将使用第二种选择:关于状态,国家和某个国家的状态的信息将根据数据库中的每个AJAX请求获取。我在示例中描述解决方案的用法value参数不依赖于服务器组件。如果使用dataUrl和,则实现的大部分内容都是相同的buildSelect

    我做了一个生动的例子来演示您的需求。

    主要的问题是,valueeditoptions使用 只有一次
    在上初始化的时间。在dataInit函数内部,可以覆盖value,但是在更改带有国家/地区的第一个选择/下拉框中的值之后,必须手动重建具有状态的第二个选择/下拉框。为此,必须理解,select
    HTML元素具有由行ID’_’和列名构成的ID:rowId +“
    _State”。此外,重要value的是editoptions必须将的重置为初始值,以便可以将任何状态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 :您将在此处找到该演示代码的最新版本。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看