Mam formularz interfejsu użytkownika, dzięki czemu kilka sekcji wymaga duplikatu Listy Wybierz HTML, aby być dynamicznie aktualizowany z jednej, dynamicznie aktualizowanej listy Wybierz.

Lista dynamicznie aktualizowana działa w porządku, w tym nowych opcjach można dodać i usunąć w locie. Następnie mogę uzyskać tę aktualizację do propagowania przez każdego z duplikatów list przy użyciu jQuery .find (). Dodałem nawet trochę logiki, aby utrzymać aktualnie wybrany indeks oryginalnej listy Wybierz.

Nie jestem w stanie wykonać, to utrzymanie wybranego stanu każdego z dwóch list wyboru, ponieważ nowe opcje są dodawane i usunięte z oryginalnej listy Wybierz. Jak każda aktualizacja do oryginalnej listy Wybierz iteruje przez każdą duplikat Wybierz listę, tracą aktualnie wybrany indeks opcji.

Oto przykład mojej konundrum - * edycja - zachęcałbym Cię do wykonania kodu, który podany poniżej i zastosowałeś teorie przed sugerując rozwiązanie , ponieważ tak daleko nie było żadnej z sugestii. Wierzę, że znajdziesz ten problem, dobrą ofertę trudniejszą niż możesz założyć na początku:

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

Ważne jest, aby pamiętać, że duplikaty listy wyboru HTML powinny pozostać nieco arbitralne, jeśli w ogóle możliwe (I.e

Z góry dziękuję!

4
lincolnberryiii 3 grudzień 2011, 23:56

4 odpowiedzi

Najlepsza odpowiedź

Wciąż nie jest w 100% pewności tego, co pytasz, ale wydaje się, że powinien to zrobić, czego szukasz i jest kilkoma lekami kodu.

(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());
            });
        } ());
    } ());

Edytuj: Zmieniłem swój znacznik

<button>add/copy</button>
<button>remove</button>
0
illvm 6 grudzień 2011, 21:49

Wystarczy ustaw aktualnie wybrany element / wartość Wybierz do pewnej zmiennej, a następnie wykonaj swoją obsługę, ostatecznie wyznacz wartość do wybranej.

0
Saboor Awan 3 grudzień 2011, 20:44

Dobra, myślę, że mam podejście do pracy do rozwiązania, jeśli nie jest niezdarny. Podstępna część nie dodaje wartości do oryginalnej listy, ponieważ dodatkowa opcja jest zawsze na końcu listy. Problem pojawia się w usunięciu opcji Wybierz, ponieważ robi to, co zmienia indeks aktualnie wybrany. Testowałem za pomocą Google Chrome na Mac bez błędów. Skomentowałem kod, aby zademonstrować, w jaki sposób zbliżyłem się do mojego rozwiązania:

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

Jest mnóstwo miejsca do modyfikowania mojego kodu, aby opcje można włożyć po aktualnie wybranymverdex, a nie dołączony do końca oryginalnej listy Wybierz. Teoretycznie, wielostEwa lista / menu powinna również działać. Mieć w tobie.

Jestem pewien, że jeden z geniuszy tutaj będzie w stanie zrobić to samo z czystszym, ładniejszym kodem niż mój. Dzięki wszystkim, którzy ocenili i skomentowali moje pierwotne pytanie! Twoje zdrowie.

0
lincolnberryiii 5 grudzień 2011, 19:07

Jeśli możesz zresetować trochę, myślę, że problem polega na ustawieniu HTML HTML wybranej listy do innej listy. Przeglądarka prawdopodobnie nie próbuje zachować aktualnie wybranego elementu, jeśli zmieni się wszystkie podstawowe HTML.

Myślę więc, że możesz spróbować wykonać wyraźnie dodanie elementów opcji do list docelowych.

Spróbuj tego jsfiddle. Jeśli wybierzesz element inny niż domyślny pierwszy element i kliknij "Dodaj", zauważ, że wybrany element jest utrzymany. Więc musisz być trochę bardziej chirurgiczny w swoim zarządzaniu przedmiotami listy docelowej.

Może to pomoże, a może tęskniłem za punktem.

0
slolife 5 grudzień 2011, 19:36