onreset и динамически генерируемые <select>'ы
Пытаюсь закрыть баг в Quickform::hierselect.
Вкратце: есть несколько связанных select'ов, выбор в первом влияет на набор option'ов в последующих. При нажатии кнопы Reset, натурально, происходит лажа: выбор в первом select'е возвращается на исходную позицию, а списки option'ов в последующих не меняются.
Написал функцию, которая отрабатывает на onreset и заполняет списки нужными значениями. Всё волшебно работает, но: функция вызывается до отработки собственно reset'а и когда отрабатывает уже он, то выбранные значения в свежеперестроенных select'ах сбрасываются. Если возвращать из функции false, то они очевидно не сбрасываются, но и не чистятся все остальные поля в форме.
Вопрос: как бы это побороть? То есть как
а) запретить сбрасывать значения в отдельных полях или
б) запустить функцию не до сброса, а после?
Пока есть решение с установкой в onreset setTimeout() с нужным кодом, но интересует более эстетичное.
-~{}~ 15.07.05 23:20:
вывалю-ка я сюда килограмм кода, чтобы было понятно, о чём вообще речь:
Если заменить в onreset фразу
на "очевидную"
то получаем вышеописанную проблему. Если вообще убрать onreset, то получаем баг #2970
Пытаюсь закрыть баг в Quickform::hierselect.
Вкратце: есть несколько связанных select'ов, выбор в первом влияет на набор option'ов в последующих. При нажатии кнопы Reset, натурально, происходит лажа: выбор в первом select'е возвращается на исходную позицию, а списки option'ов в последующих не меняются.
Написал функцию, которая отрабатывает на onreset и заполняет списки нужными значениями. Всё волшебно работает, но: функция вызывается до отработки собственно reset'а и когда отрабатывает уже он, то выбранные значения в свежеперестроенных select'ах сбрасываются. Если возвращать из функции false, то они очевидно не сбрасываются, но и не чистятся все остальные поля в форме.
Вопрос: как бы это побороть? То есть как
а) запретить сбрасывать значения в отдельных полях или
б) запустить функцию не до сброса, а после?
Пока есть решение с установкой в onreset setTimeout() с нужным кодом, но интересует более эстетичное.
-~{}~ 15.07.05 23:20:
вывалю-ка я сюда килограмм кода, чтобы было понятно, о чём вообще речь:
Код:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>hierselect megabugfix</title>
</head>
<body>
<form action="" method="get" id="frmHierselect" onreset="setTimeout(function () { hierselectReset(this, 'hotels'); }, 50);">
<div>
<table border="0">
<tr>
<td align="right" valign="top"><b>Input box:</b></td>
<td valign="top" align="left"><input type="text" name="foo" value="" size="32" /></td>
</tr>
<tr>
<td align="right" valign="top"><b>Location:</b></td>
<td valign="top" align="left"><script type="text/javascript">
//<![CDATA[
if (typeof _qf_hierselect == 'undefined') {
_qf_hierselect = {};
_qf_hierselect_defaults = {};
}
_qf_hierselect['hotels'] = [
{'0': {"0":"London", "1":"Manchester", "2":"Liverpool"}, '2': {"5":"Fort Worth", "6":"Boston", "7":"Los Angeles"}},
{'0': {'0': {"0":"London Hotel 1", "1":"London Hotel 2"}, '1': {"0":"Manchester Hotel 1", "1":"Manchester Hotel 2"}, '2': {"1":"Liverpool Hotel 1", "3":"Liverpool Hotel 2"}},
'2': {'5': {"1":"Fort Worth Hotel 1", "3":"Fort Worth Hotel 2"}, '6': {"1":"Boston Hotel 1", "3":"Boston Hotel 2"}, '7': {"1":"Los Angeles Hotel 1", "2":"Los Angeles Hotel 2"}}}
];
_qf_hierselect_defaults['hotels'] = [2, 6, 3];
// Recursive function to get rid of eval()
function findOptions(ary, keys)
{
var key = keys.shift();
if (!key in ary) {
return {};
} else if (0 == keys.length) {
return ary[key];
} else {
return findOptions(ary[key], keys);
}
}
function swapOptionsNew(form, groupName, selectIndex)
{
var hsValue = [];
var ctl;
for (var i = 0; i < _qf_hierselect[groupName].length; i++) {
ctl = form[groupName+'['+i+']'];
if (!ctl) {
ctl = form[groupName+'['+i+'][]'];
}
if (i <= selectIndex) {
hsValue[i] = ctl.value;
} else {
ctl.length = 0;
}
}
var optionList = findOptions(_qf_hierselect[groupName][selectIndex], hsValue);
var n = selectIndex + 1;
ctl = form[groupName+'['+ n +']'];
if (!ctl) {
ctl = form[groupName+'['+ n +'][]'];
}
var j = 0;
for (i in optionList) {
ctl.options[j++] = new Option(optionList[i], i, false, false);
}
if (selectIndex + 1 < _qf_hierselect[groupName].length) {
swapOptionsNew(form, groupName, selectIndex + 1);
}
}
function hierselectReset(form, groupName)
{
for (var i = 0; i <= _qf_hierselect[groupName].length; i++) {
ctl = form[groupName+'['+i+']'];
if (!ctl) {
ctl = form[groupName+'['+i+'][]'];
}
for (var j = 0; j < ctl.options.length; j++) {
if (ctl.options[j].value == _qf_hierselect_defaults[groupName][i]) {
ctl.options[j].selected = true;
//alert(ctl.options[j].value + ctl.options[j].text);
}
}
if (i < _qf_hierselect[groupName].length) {
var optionList = findOptions(_qf_hierselect[groupName][i], _qf_hierselect_defaults[groupName].slice(0, i + 1));
var n = i + 1;
ctl = form[groupName+'['+ n +']'];
if (!ctl) {
ctl = form[groupName+'['+ n +'][]'];
}
j = 0;
for (var k in optionList) {
ctl.options[j++] = new Option(optionList[k], k, false, false);
}
}
}
return false;
}
//]]>
</script><select name="hotels[0]" onchange="swapOptionsNew(this.form, 'hotels', 0);">
<option value="0">England</option>
<option value="2" selected="selected">USA</option>
</select> <select name="hotels[1]" onchange="swapOptionsNew(this.form, 'hotels', 1);">
<option value="5">Fort Worth</option>
<option value="6" selected="selected">Boston</option>
<option value="7">Los Angeles</option>
</select> <select name="hotels[2]">
<option value="1">Boston Hotel 1</option>
<option value="3" selected="selected">Boston Hotel 2</option>
</select></td>
</tr>
<tr>
<td align="right" valign="top"><b></b></td>
<td valign="top" align="left"><input name="buttons[btnSubmit]" value="Submit" type="submit" /> <input name="buttons[btnReset]" value="Reset" type="reset" /></td>
</tr>
</table>
</div>
</form>
</body>
</html>
Код:
setTimeout(function () { hierselectReset(this, 'hotels'); }, 50);
Код:
hierselectReset(this, 'hotels');