Using JavaScript and jQuery, how can I save the selected state of a dynamically updated HTML select element?

I have a form user interface according to which several sections require that the duplicate HTML select list is dynamically updated from one dynamically updated select list.

A dynamically updated list works very well, as new parameters can be added and removed on the fly. Then I can get this update for distribution through each of the duplicate lists using jQuery.find (). I even added some logic to maintain the current selected index of the original select list.

What I cannot do is save the selected state of each of the duplicate lists, as new parameters are added and removed from the original selection list. Since each update of the original selection list is repeated through each duplicate selection list, they lose their current selected parameter.

Here is an example of my puzzle - * EDIT . I would advise you to try and execute the code that I provided below and apply your theories before proposing a solution, since none of the sentences have worked so far. I believe that you will find this problem much more complicated than you might have expected 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 duplicate HTML picklists should remain somewhat arbitrary, if at all possible (i.e. no identifiers), since this method should be applied in general to other dynamically created picklists in the document.

Thanks in advance!

+4
source share
4 answers

Still not 100% sure what you are asking, but it looks like this should do what you are looking for, and a few more lines of code.

 (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

 <button>add/copy</button> <button>remove</button> 
0
source

just set the currently selected item / value to select a variable, then do your operation, finally re-select the value to select.

0
source

Well, I think I have an acceptable approach to the solution, if not clumsy. The difficult part does not add value to the original list, because the added option is always at the end of the list. The problem is removing the selection option, because it changes the index of the current selectedIndex. I tested Google Chrome on Mac without errors. I commented on 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 are many possibilities for modifying my code so that options can be inserted after the currently selected Index, rather than being added to the end of the original selection list. Theoretically, a multi-position list / menu should also work. You have.

I am sure that one of the geniuses here can do the same with a clean, beautiful code than mine. Thanks to everyone who looked at my original question and commented on it! Greetings.

0
source

If you can reset a bit, I think the problem is that you are setting your HTML code for the selected list to another HTML list. The browser may not be trying to save the currently selected item if all basic HTML files are modified.

So, I think that you can try to explicitly add option elements to target lists.

Try jsfiddle . If you select an item other than the first default item and click "add", note that the selected item is saved. Therefore, you need to be a little more surgical in managing your list of goals.

Maybe this will help or maybe I missed this moment.

0
source

Source: https://habr.com/ru/post/1384499/


All Articles