使用JavaScript和JQuery,我如何维护一个动态更新的HTML选择元素的选择状态
Using JavaScript and JQuery, How Can I Maintain the Selected State of a Dynamically-Updated HTML Select Element?
我有一个表单UI,其中几个部分需要从单个动态更新的选择列表中动态更新重复的HTML选择列表。
动态更新列表工作得很好,因为可以动态添加和删除新选项。然后,我可以使用JQuery .find()让这个更新在每个重复列表中传播。我甚至添加了一些逻辑来维护原始选择列表的当前选定索引。
我不能做的是维护每个重复选择列表的选择状态,因为从原始选择列表中添加和删除了新的选项。当对原始选择列表的每次更新遍历每个重复的选择列表时,它们会丢失当前选择的选项索引。
这是我的一个难题的例子——*EDIT——我鼓励你尝试并执行我下面提供的代码,并在提出解决方案之前应用你的理论,因为到目前为止没有一个建议有效。我相信您会发现这个问题比您一开始想象的要棘手得多:
<form>
<div id="duplicates">
<!--// I need for each of these duplicates to maintain their currently selected option index as the original updates dynamically //-->
<select>
</select>
<select>
</select>
<select>
</select>
</div>
<div>
<input type="button" value="add/copy" onclick="var original_select = document.getElementById('original'); var new_option = document.createElement('option'); new_option.text = 'Option #' + original_select.length; new_option.value = new_option.text; document.getElementById('original').add(new_option); original_select.options[original_select.options.length-1].selected = 'selected'; updateDuplicates();" />
<input type="button" value="remove" onclick="var original_select = document.getElementById('original'); var current_selected = original_select.selectedIndex; original_select.remove(original_select[current_selected]); if(original_select.options.length){original_select.options[current_selected < original_select.options.length?current_selected:current_selected - 1].selected = 'selected';} updateDuplicates();" />
<select id="original">
</select>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
function updateDuplicates(){
$("#duplicates").find("select").html($("#original").html());
}
</script>
</form>
重要的是要注意,重复的HTML选择列表应该保持某种程度上的任意,如果可能的话(即;没有ID),因为该方法需要应用于整个文档中其他动态创建的选择列表。
提前感谢!
仍然不能100%确定你在问什么,但似乎这应该做你正在寻找的,是几行代码。
(function () {
function updateDuplicates() {
$("#duplicates").find("select").html($("#original").html());
$('#duplicates select').each(function () {
var lastSelectedValue = $(this).data('lastSelectedValue');
$(this).val(lastSelectedValue || $(this).val());
});
}
$(document).ready(function () {
$('button:contains(remove)').bind('click', function (e) {
e.preventDefault();
var original_select = document.getElementById('original'),
current_selected = original_select.selectedIndex;
original_select.remove(original_select[current_selected]);
if (original_select.options.length) {
original_select.options[current_selected < original_select.options.length ? current_selected : current_selected - 1].selected = 'selected';
}
updateDuplicates();
});
$('button:contains(add/copy)').bind('click', function (e) {
e.preventDefault();
var original_select = document.getElementById('original'),
new_option = document.createElement('option');
new_option.text = 'Option #' + original_select.length;
new_option.value = new_option.text;
document.getElementById('original').add(new_option);
original_select.options[original_select.options.length - 1].selected = 'selected';
updateDuplicates();
});
$('#duplicates select').bind('change', function () {
$(this).data('lastSelectedValue', $(this).val());
});
} ());
} ());
编辑:我把你的标记改成了
<button>add/copy</button>
<button>remove</button>
将当前选中的项/值设置为某个变量,然后进行操作,最后重新选择值
好吧,我想我有一个可行的解决方案,如果不是一个笨拙的方法。棘手的部分不是向原始列表添加值,因为添加的选项总是在列表的末尾。问题出现在删除select选项时,因为这样做会更改当前选定的索引。我在Mac上使用谷歌浏览器进行了测试,没有出现任何错误。我对代码进行了注释,以演示如何处理我的解决方案:
<form>
<div id="duplicates">
<!--// Each of these select lists should maintain their currently selected index //-->
<select>
</select>
<select>
</select>
<select>
</select>
</div>
<div>
<!--// Using a generic function to capture each event //-->
<input type="button" value="add/copy" onClick="updateDuplicates('add');" />
<input type="button" value="remove" onClick="updateDuplicates('remove');" />
<select id="original">
</select>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
function updateDuplicates(editMode){
///* Capture the selectedIndex of each select list and store that value in an Array *///
var original_select = document.getElementById('original');
var current_selected = new Array();
$("#duplicates").find("select").each(function(index, element) {
current_selected[index] = element.selectedIndex;
});
switch(editMode){
case "add":
var new_option = document.createElement('option');
new_option.text = 'Option #' + original_select.length;
new_option.value = new_option.text;
original_select.add(new_option);
original_select.options[original_select.options.length-1].selected = 'selected';
///* Traverse each select element and copy the original into it, then set the defaultSelected attribute for each *///
$("#duplicates").find("select").each(function(index, element){
$(element).html($("#original").html());
///* Retrieve the currently selected state stored in the array from before, making sure it is a non -1 value, then set the defaultSelected attribute of the currently indexed element... *///
if(current_selected[index] > -1){
element.options[current_selected[index]].defaultSelected = true;
}
});
break;
case "remove":
var current_index = original_select.selectedIndex;
original_select.remove(original_select[current_index]);
///* Thou shalt not remove from thine empty list *///
if(original_select.options.length){
original_select.options[current_index > 0?current_index - 1:0].selected = 'selected';
}
///* Traverse each select element and copy the original into it... *///
$("#duplicates").find("select").each(function(index, element){
$(element).html($("#original").html());
///* Avoid operating on empty lists... *///
if(original_select.options.length){
///* Retrieve the currently selected state stored in the array from before, making sure it is a non -1 value... *///
if(current_selected[index] > -1){
///* If the stored index state is less or equal to the currently selected index of the original... *///
if(current_selected[index] <= current_index){
element.options[current_selected[index]].defaultSelected = true;
///* ...otherwise, the stored index state must be greater than the currently selected index of the original, and therefore we want to select the index after the stored state *///
}else{
element.options[current_selected[index] - 1].defaultSelected = true;
}
}
}
});
}
}
</script>
</form>
有足够的空间来修改我的代码,以便可以将选项插入到当前选定的索引之后,而不是附加到原始选择列表的末尾。从理论上讲,一个多选择列表/菜单也应该工作。吃吧。
我相信这里的一个天才能够用比我的代码更干净、更漂亮的代码做同样的事情。感谢所有对我最初的问题进行评论和评论的人!欢呼。
如果您可以重置一点,我认为问题是您将选择列表的HTML设置为另一个列表的HTML。如果所有的底层html都被更改了,浏览器可能不会尝试保留当前选中的项。
所以,我认为你可能会尝试做的是显式地将选项元素添加到目标列表中。
试试这个。如果您选择了默认第一项以外的项并单击"添加",请注意所选的项将被维护。因此,在管理目标列表项时,您需要更精确一些。
也许会有帮助,也许我没抓住重点。
- 从a-z中随机选择一个字母
- AngularJS ng选项在选择一个选项后删除了默认的空白值
- 在下拉列表中选择一个选项的值
- 在类JavaScript选择的另一个元素中选择一个标记元素
- Jquery:当两个或多个条件为true时,选择一个元素
- 可以使用createRange选择一个空范围
- 选择一个元素,使其最近的具有特殊属性的父元素具有特殊值
- 使用 Jquery 选择一个 td 元素
- 当使用jQuery/Javascript选择一个多选时,如何使所有值都不被选中:
- 在一组复选框中,一次只允许选择一个
- 如何强制用户从下拉列表和按钮中选择一个值以启用保存按钮
- 从数组中选择一个变量
- 正在读取<p: 选择一个菜单/>在onchange回调中
- 在输入字段中选择一个值,然后用相应的数据填充另一个字段
- 如何以编程方式在 jsTree 中选择一个节点并打开所有父节点
- Asp.net 引导下拉菜单 - 选择一个项目
- 如何根据 jsp 中数据库中的值在下拉列表中选择一个值
- 通过硒选择一个javascript下拉列表
- 选择一个从 mysql 返回选中/未选中复选框的对象
- 如何在 PHP 中使用 OnChange 事件的下拉列表中选择一个选项后,对大量数据行设置分页