Jqgrid incorrect sélectionne les options de l'option déroulante dans la zone d'édition

J'utilise l'édition de formulaire. Il existe deux boîtes de sélection sous la forme. Une boîte de sélection est le pays, une autre boîte de sélection est l'état. Le champ de sélection d'état dépend du pays sélectionné et sera rempli dynamiquement. Par exemple:

Pays:

US (valeur d'option = 1)
Royaume-Uni (option value = 2)

État pour les États-Unis:

Alabama (valeur d'option = 1)
Californie (valeur d'option = 2)
Floride (valeur d'option = 3)
Hawaii (valeur d'option = 4)

État pour le Royaume-Uni:

Londres (valeur d'option = 5)
Oxford (valeur d'option = 6)

Comme vous pouvez le voir ci-dessus, l'ID d'état pour Royaume-Uni commence par 5. Lorsque je modifie un enregistrement qui contient Country id=2 (UK) et State id=6 (Oxford) , le formulaire d'édition s'affiche correctement – Pays est Royaume-Uni et Etat Est Oxford. Mais si vous déplacez la boîte de sélection d'état, le texte de l'option est correct (il montre London Oxford), mais la valeur de l'option commencera à partir de 0. Ce qui devrait être correct, c'est que la valeur de l'option commence à partir de 5.

Si vous sélectionnez et modifiez la liste déroulante du pays vers les États-Unis, reportez-vous à nouveau au Royaume-Uni, la valeur de l'option sera remplie correctement (commence à partir de 5).

Ma question est de savoir comment remplir la boîte de sélection de l'état avec la valeur d'option correcte en fonction du pays dans la zone d'édition lorsque le formulaire d'édition est chargé?

La réponse à votre question dépend un peu de la source où vous recevez les informations affichées sous «État pour les États-Unis» et «État pour le Royaume-Uni». Les deux possibilités sont supportées par jqGrid: 1) l'utilisation du paramètre de value de editoptions 2) l'utilisation du paramètre dataUrl et buildSelect des éditions . La première façon est la meilleure en cas d'édition locale ou dans le cas où la liste des options possibles est statique. Le deuxième choix sera utilisé dans le cas où les informations sur les états, les pays et les états de certains pays seront obtenues par demande AJAX de la base de données. Je décris la solution sur l'exemple du paramètre de l'utilisation de la value pour ne pas avoir de dépendance aux composants du serveur. La plupart des implémentations sont les mêmes en cas d'utilisation de dataUrl et de buildSelect .

J'ai fait l'exemple en direct qui démontre ce dont vous avez besoin.

Le problème principal est que la value des editoptions n'est utilisée qu'une fois au moment de l'initialisation. À l'intérieur de la fonction dataInit , on peut écraser la value , mais après la modification de la valeur dans la première boîte de sélection / liste déroulante avec les pays, la deuxième sélection / liste déroulante avec les états doit être reconstruite manuellement. Pour ce faire, il faut comprendre que l'élément HTML sélectionné a un identifiant construit à partir de l'ID de la ligne '_' et le nom de la colonne: rowId + "_State". De plus, il est important que la value des editoptions soit réinitialisée à la valeur initiale, de sorte que tout identifiant d'état puisse être décodé sur le nom de l'état.

Voici le code de l'exemple :

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

MISE À JOUR : J'ai mis à jour le code ci-dessus pour le faire fonctionner en cas d'édition de formulaire également. Vous pouvez le voir en direct ici . Parce que jqGrid ne prend pas en charge l'édition locale pour l'édition de formulaire, je n'ai pas pu tester le code. Néanmoins, j'espère que j'ai tiré le meilleur parti des changements requis.

MISE À JOUR 2 : j'ai étendu le code ci-dessus pour prendre en charge

  1. Édition en ligne, édition de formulaire, barre d'outils de recherche et recherche avancée
  2. Les boutons de navigation précédents ou suivants dans le formulaire d'édition
  3. Amélioration du support du clavier dans les choix (un problème avec la sélection dépendante rafraîchissante dans certains navigateurs est réparé)

La nouvelle version de la démo est ici . Le code modifié de la démo que vous trouvez ci-dessous:

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

MISE À JOUR 3 : La dernière version du code de démo que vous trouverez ici .

J'utilise l'édition de formulaire. Il existe trois boîtes de sélection dans le formulaire. Une boîte de sélection est le pays, une boîte de sélection est la ville, une autre boîte de sélection est la rue. La boîte de sélection de la ville dépend du pays sélectionné et sera remplie dynamiquement. La boîte de sélection de rue dépend de la ville sélectionnée et sera remplie dynamiquement. Je sauvegarde Country, City, Street dans MySQL. Si je choisis un pays, comment changer la boîte de sélection de la ville de la table MySQL