Javascript jqgrid 在编辑框中不正确的选择下拉选项值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4469650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jqgrid incorrect select drop down option values in edit box
提问by Alex
I am using form edit. There are two select boxes in the form. One select box is the country, another select box is the state. The state select box depends on the country selected and will be populated dynamically. For example:
我正在使用表单编辑。表单中有两个选择框。一个选择框是国家,另一个选择框是州。州选择框取决于所选的国家,并将动态填充。例如:
Country:
国家:
US (option value=1)
UK (option value=2)
美国(期权价值=1)
英国(期权价值=2)
State for US:
美国的州:
Alabama (option value=1)
California (option value=2)
Florida (option value=3)
Hawaii (option value=4)
阿拉巴马州(期权价值=1)
加利福尼亚州(期权价值=2)
佛罗里达州(期权价值=3)
夏威夷(期权价值=4)
State for UK:
英国的州:
London (option value=5)
Oxford (option value=6)
伦敦(期权价值=5)
牛津(期权价值=6)
As you can see above the id of state for uk starts with 5. When I edit a record which contained Country id=2 (UK)
and State id=6 (Oxford)
, the edit form will shows correctly - Country is UK and State is Oxford. But if you drop down the state select box the option text is correct (it shows London Oxford) but the option value will starts from 0. What should be correct is that the option value should starts from 5.
正如您在上面看到的,英国的州 ID 以 5 开头。当我编辑包含Country id=2 (UK)
和的记录时State id=6 (Oxford)
,编辑表单将正确显示 - 国家是英国,州是牛津。但是如果你下拉状态选择框,选项文本是正确的(它显示伦敦牛津)但选项值将从 0 开始。应该正确的是选项值应该从 5 开始。
If you select and change the country drop down box to US then change back again to UK, the option value will be populated correct (starts from 5).
如果您选择并将国家下拉框更改为美国,然后再次更改回英国,则选项值将正确填充(从 5 开始)。
My question is, how can we populate the select box for the state with the correct option value based on the country in edit box when the edit form loads?
我的问题是,当编辑表单加载时,我们如何根据编辑框中的国家/地区使用正确的选项值填充状态的选择框?
回答by Oleg
The answer on your question depend a little from the source where you receive the information about displayed under "State for US" and "State for UK". The are two possibilities supported by jqGrid: 1) the usage of value
parameter of editoptions2) the usage of dataUrl
and buildSelect
parameter of the editoptions. The first way is the best one in case of local editing or in the case if the list of possible options is static. The second choose will be used in the case, that the information about states, countries and the states of some country will be get per AJAX request from the database. I describe the solution on the example the usage of value
parameter to have no dependencies to the server components. The most parts on the implementation are the same in case of the usage of dataUrl
and buildSelect
.
您的问题的答案在一定程度上取决于您收到“State for US”和“State for UK”下显示的信息的来源。的是由支持的jqGrid两种可能性:1)的使用value
的参数editoptions2)的使用dataUrl
和buildSelect
参数的editoptions。在本地编辑或可能选项列表是静态的情况下,第一种方法是最好的方法。第二个选择将用于这种情况,即每个 AJAX 请求将从数据库中获取有关州、国家和某个国家的州的信息。我在示例中描述了解决方案的用法value
参数不依赖于服务器组件。在使用dataUrl
和 的情况下,实现的大部分内容是相同的buildSelect
。
I made the live examplewhich demonstrate what you need.
我做了一个活生生的例子来展示你所需要的。
The main problem is that the value
of the editoptions
are used only onceat the time on the initialization. Inside of dataInitfunction one can overwrite the value
, but after the changing of the value in the first select/drop-down box with countries the second select/drop-down box with states must be rebuild manually. To do so one have to understand, that the select HTML element has id constructed from row id '_' and the column name: rowId + "_State". Moreover it is important, that the the value
of the editoptions
must be reset to the initial value, so that any state id can be decoded to the state name.
主要的问题是,value
的editoptions
使用只有一次在上初始化的时间。在dataInit函数内部可以覆盖value
,但在第一个选择/下拉框中的值更改为国家后,必须手动重建第二个选择/下拉框的状态。要做到这一点,你必须明白,select HTML 元素的 id 是由行 id '_' 和列名构造的:rowId + "_State"。此外重要的value
是,editoptions
必须将 的 重置为初始值,以便任何状态 id 都可以解码为状态名称。
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 working with in case of form editing too. You can see it live here. Because jqGrid not support local editing for form editing I could not tested the code. Nevertheless I hope that I made the most of required changes.
更新:我更新了上面的代码,使其在表单编辑时也能使用。你可以在这里看到它。因为 jqGrid 不支持表单编辑的本地编辑,所以我无法测试代码。尽管如此,我希望我能充分利用所需的更改。
UPDATED 2: I extended the above code to support
更新 2:我扩展了上面的代码以支持
- Inline editing, Form editing, Searching Toolbar and Advanced Searching
- The previous or next navigation buttons in the editing form
- Improving keyboard support in selects (problem with refreshing dependent select in some browsers are fixed)
- 内联编辑、表单编辑、搜索工具栏和高级搜索
- 编辑表单中的上一个或下一个导航按钮
- 改进选择中的键盘支持(修复了某些浏览器中刷新依赖选择的问题)
The new version of the demo is here. The modified code of the demo you 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: The last version of the code of the demo you will find here.
更新 3:您将在此处找到演示代码的最新版本。
回答by Owen
I am using form edit. There are three select boxes in the form. One select box is the country, one select box is the city,another select box is the street. The city select box depends on the country selected and will be populated dynamically. The street select box depends on the city selected and will be populated dynamically. I save Country、City、Street in MySQL. If I choose country,how do change city select box from MySQL table
我正在使用表单编辑。表单中有三个选择框。一个选择框是国家,一个选择框是城市,另一个选择框是街道。城市选择框取决于所选的国家,并将动态填充。街道选择框取决于所选的城市并将动态填充。我在 MySQL 中保存 Country、City、Street。如果我选择国家,如何更改 MySQL 表中的城市选择框