it-swarm.com.de

jqgrid falsche Auswahl-Dropdown-Optionswerte im Bearbeitungsfeld

Ich verwende Formularbearbeitung. Das Formular enthält zwei Auswahlfelder. Ein Auswahlfeld ist das Land, ein anderes Auswahlfeld ist der Staat. Das Statusauswahlfeld hängt von dem ausgewählten Land ab und wird dynamisch ausgefüllt. Zum Beispiel:

Land:

US (Optionswert = 1)
UK (Optionswert = 2)

Bundesstaat für USA:

Alabama (Optionswert = 1)
Kalifornien (Optionswert = 2)
Florida (Optionswert = 3)
Hawaii (Optionswert = 4)

Bundesstaat für Großbritannien:

London (Optionswert = 5)
Oxford (Optionswert = 6)

Wie Sie oben sehen können, beginnt die ID von state für uk mit 5. Wenn ich einen Datensatz bearbeite, der Country id=2 (UK) und State id=6 (Oxford) enthielt, wird das Bearbeitungsformular korrekt angezeigt - Land ist UK und State ist Oxford. Wenn Sie jedoch das Statusauswahlfeld ausklappen, ist der Optionstext korrekt (er zeigt London Oxford), der Optionswert beginnt jedoch bei 0. Das richtige Argument ist, dass der Optionswert bei 5 beginnt.

Wenn Sie das Dropdown-Feld für das Land auswählen und in USA ändern, dann wieder auf UK zurücksetzen, wird der Optionswert korrekt ausgefüllt (beginnt bei 5).

Meine Frage ist, wie können wir das Auswahlfeld für den Status mit dem korrekten Optionswert basierend auf dem Land im Bearbeitungsfeld auffüllen, wenn das Bearbeitungsformular geladen wird?

14
Alex

Die Antwort auf Ihre Frage hängt ein wenig von der Quelle ab, von der Sie die Informationen erhalten, die unter "State for US" und "State for UK" angezeigt werden. Es gibt zwei Möglichkeiten, die von jqGrid unterstützt werden: 1) Die Verwendung des Parameters valuevon editoptions 2) Die Verwendung von dataUrlund des buildSelectname__-Parameters des editoptions . Der erste Weg ist der beste für lokale Bearbeitung oder für den Fall, dass die Liste der möglichen Optionen statisch ist. Die zweite Auswahl wird in dem Fall verwendet, dass die Informationen über Staaten, Länder und die Staaten eines Landes per AJAX Anfrage aus der Datenbank abgerufen werden. Ich beschreibe die Lösung am Beispiel der Verwendung des Parameters valuename__, um keine Abhängigkeiten zu den Serverkomponenten zu haben. Die meisten Teile der Implementierung sind bei Verwendung von dataUrlund buildSelectdie gleichen.

Ich habe das Live-Beispiel die zeigen, was Sie brauchen.

Das Hauptproblem ist, dass valuedes editoptionszum Zeitpunkt der Initialisierung nur einmal verwendet wird. Innerhalb von dataInit function kann man die valueüberschreiben, aber nach der Änderung des Wertes in der ersten Auswahl-/Dropdown-Box mit Ländern muss die zweite Auswahl-/Dropdown-Box mit Status manuell neu erstellt werden. Dazu muss man verstehen, dass das select-HTML-Element aus der Zeilen-ID '_' und dem Spaltennamen eine id aufgebaut hat: rowId + "_State". Außerdem ist es wichtig, dass der valuedes editoptionsauf den ursprünglichen Wert zurückgesetzt werden muss, damit jede Status-ID in den Statusnamen dekodiert werden kann.

Hier ist der Code aus dem Beispiel :

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

AKTUALISIERT: Ich habe den obigen Code überarbeitet, damit er auch für die Bearbeitung von Formularen verwendet werden kann. Sie können es live hier sehen. Da jqGrid keine lokale Bearbeitung für die Formularbearbeitung unterstützt, konnte ich den Code nicht testen. Trotzdem hoffe ich, dass ich die erforderlichen Änderungen bestmöglich gemacht habe.

UPDATED 2: Ich habe den obigen Code zur Unterstützung erweitert

  1. Inline-Bearbeitung, Formularbearbeitung, Suchsymbolleiste und erweiterte Suche
  2. Die vorherigen oder nächsten Navigationsschaltflächen im Bearbeitungsformular
  3. Verbesserung der Tastaturunterstützung bei Auswahlmöglichkeiten (Probleme mit der Aktualisierung der abhängigen Auswahl in einigen Browsern wurden behoben)

Die neue Version der Demo ist hier . Den geänderten Code der Demo finden Sie unten:

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

AKTUALISIERT 3: Die letzte Version des Codes der Demo finden Sie hier .

35
Oleg

Ich verwende Formularbearbeitung. Es gibt drei Auswahlfelder im Formular. Ein Auswahlfeld ist das Land, ein Auswahlfeld ist die Stadt, ein anderes Auswahlfeld ist die Straße. Das Auswahlfeld für die Stadt hängt von dem ausgewählten Land ab und wird dynamisch aufgefüllt. Das Auswahlfeld für die Straße hängt von der ausgewählten Stadt ab und wird dynamisch aufgefüllt. Ich rette Land 、 Stadt 、 Straße in MySQL. Wenn ich das Land wähle, wie ändern Sie die Stadt aus der MySQL-Tabelle

0
Owen