简体   繁体   English

使用JavaScript和JQuery,如何维护动态更新的HTML选择元素的选定状态?

[英]Using JavaScript and JQuery, How Can I Maintain the Selected State of a Dynamically-Updated HTML Select Element?

I have a form UI whereby several sections require duplicate HTML select list to be updated dynamically from a single, dynamically-updatable select list. 我有一个表单UI,其中几个部分需要重复的HTML选择列表,以便从单个可动态更新的选择列表中动态更新。

The dynamically-updatable list works just fine, in that new options can be added and removed on-the-fly. 动态可更新列表工作正常,因为可以即时添加和删除新选项。 I can then get this update to propagate through each of the duplicate lists using JQuery .find(). 然后,我可以使用JQuery .find()将此更新传播到每个重复列表中。 I have even added a bit of logic to maintain the currently selected index of the original select list. 我甚至添加了一些逻辑来维护原始选择列表的当前选定索引。

What I'm not able to do is maintain the selected state of each of the duplicate select lists as new options are added and removed from the original select list. 我无法做的是在原始选择列表中添加和删除新选项时,保持每个重复选择列表的选定状态。 As each update to the original select list iterates through each duplicate select list, they lose their currently selected option index. 当对原始选择列表的每次更新迭代通过每个重复选择列表时,它们将丢失其当前选择的选项索引。

Here is an example of my conundrum-- *EDIT --I would encourage you to try and execute the code I've provided below and apply your theories before suggesting a solution, as none of the suggestions so far have worked. 这是我的难题的一个例子 - *编辑 - 我会鼓励你尝试执行我在下面提供的代码并提出解决方案之前应用你的理论,因为到目前为止没有任何建议有效。 I believe you will find this problem a good deal trickier than you might assume at first: 我相信你会发现这个问题比你最初想象的要困难得多:

<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>

It is important to note that the duplicate HTML select lists should remain somewhat arbitrary, if at all possible (ie; no ID's) as this method needs to apply generically to other dynamically-created select lists throughout the document. 重要的是要注意,重复的HTML选择列表应该保持一定的任意性(如果没有ID),因为此方法需要一般性地应用于整个文档中的其他动态创建的选择列表。

Thanks in advance! 提前致谢!

只需将当前选择的项目/值设置为某个变量,然后执行操作,最后重新选择值。

Okay, I think I have a workable approach to a solution, if not a clumsy one. 好吧,我认为我有一个可行的解决方案,如果不是一个笨拙的解决方案。 The tricky part isn't adding a value to the original list, because the added option is always at the end of the list. 棘手的部分是不向原始列表添加值,因为添加的选项始终位于列表的末尾。 The problem comes in removing a select option because doing so changes the index of the currently selectedIndex. 删除select选项会出现问题,因为这样做会更改当前selectedIndex的索引。 I've tested using Google Chrome on a Mac with no errors. 我已经在Mac上使用Google Chrome进行了测试,没有任何错误。 I have commented the code to demonstrate how I approached my solution: 我已经评论了代码,以演示我如何处理我的解决方案:

<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>

There is plenty of room to modify my code so that options can be inserted after the currently selectedIndex rather than appended to the end of the original select list. 有足够的空间来修改我的代码,以便可以在当前selectedIndex之后插入选项,而不是附加到原始选择列表的末尾。 Theoretically, a multi-select list/menu should work as well. 从理论上讲,多选列表/菜单也应该有效。 Have at thee. 在你身边。

I'm sure one of the geniuses here will be able to do this same thing with cleaner, prettier code than mine. 我敢肯定,这里的天才之一将能够用比我更清洁,更漂亮的代码做同样的事情。 Thanks to everyone who reviewed and commented on my original question! 感谢所有评论和评论我原始问题的人! Cheers. 干杯。

If you can reset a little, I think that the problem is you are setting your select list's HTML to another list's HTML. 如果您可以重置一点,我认为问题是您将选择列表的HTML设置为另一个列表的HTML。 The browser probably doesn't try to preserve the currently selected item if all the of underlying html is being changed. 如果所有底层html都被更改,浏览器可能不会尝试保留当前选定的项目。

So, I think what you might try doing is explicitly adding the option elements to the target lists. 所以,我认为你可能尝试做的是明确地将选项元素添加到目标列表。

Try this jsfiddle . 试试这个jsfiddle If you select an item other than the default first item and click "add", notice that the selected item is maintained. 如果选择默认第一项以外的项目并单击“添加”,请注意保留所选项目。 So you need to be a little more surgical in your managing of the target list items. 因此,您需要在管理目标列表项目时多做一些手术。

Maybe that'll help or maybe I missed the point. 也许这会有所帮助,也许我错过了这一点。

Still not 100% sure what you're asking but it seems like this should do what you're looking for and is a few less lines of code. 仍然不是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());
            });
        } ());
    } ());

EDIT: I changed your markup to be 编辑:我改变了你的标记

<button>add/copy</button>
<button>remove</button>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我无法选择使用jquery动态创建的html元素 - I can't select an html element that was created dynamically with jquery 如何选择使用jQuery / Javascript在html中动态创建的单个元素值? - How to select single element value which created dynamically in html using jQuery / Javascript? 我如何在 javascript 中使用 jquery 循环 html 元素? - How can i loop html element using jquery in javascript? 当“不相关”的html select元素未选择任何选项时,如何退出jQuery事件? - How can I exit from a jQuery event when an “unrelated” html select element has had no option selected? 如何使用 jQuery、JavaScript 和 HTML 动态设置下拉列表的选定选项? - How do I dynamically set the selected option of a drop-down list using jQuery, JavaScript and HTML? 如何在使用Javascript选择的html select元素中创建所有值 - How do I make all values in html select element selected using Javascript jQuery,如何选择动态生成的html元素 - jQuery, how to select dynamically generated html element 如何选择在 Angular 中动态加载的 html 元素? - How can I select a html element which loaded dynamically in Angular? 在使用JavaScript或JQuery选择HTML中的选定项目之后,如何禁用项目? - How do I disable items after the selected item in an HTML select using JavaScript or JQuery? 使用Javascript选择链接时,如何隐藏HTML元素? - How can I hide a HTML element when a link is selected with Javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM