4

動的に更新可能な単一の選択リストから動的に更新するために、複数のセクションで重複した HTML 選択リストを必要とするフォーム UI があります。

動的に更新可能なリストは、新しいオプションをオンザフライで追加および削除できるという点で、うまく機能します。次に、JQuery .find() を使用して、この更新を各重複リストに反映させることができます。元の選択リストの現在選択されているインデックスを維持するためのロジックも少し追加しました。

私ができないことは、元の選択リストに新しいオプションが追加および削除されるときに、重複する選択リストのそれぞれの選択状態を維持することです。元の選択リストを更新するたびに、複製された各選択リストを反復処理すると、現在選択されているオプション インデックスが失われます。

これが私の難問の例です- *編集-これまでの提案はどれも機能していないため、解決策を提案する前に、以下に提供するコードを試して実行し、理論を適用することをお勧めします. この問題は、最初に想定したよりもかなりトリッキーであることがわかると思います。

<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 なしで) ある程度恣意的なままにする必要があることに注意することが重要です。

前もって感謝します!

4

4 に答える 4

0

少しリセットできれば、問題は選択リストのHTMLを別のリストのHTMLに設定していることだと思います。基になるhtmlのすべてが変更されている場合、ブラウザはおそらく現在選択されているアイテムを保持しようとはしません。

ですから、あなたがやろうとしているのは、ターゲットリストにオプション要素を明示的に追加することだと思います。

このjsfiddleを試してください。デフォルトの最初のアイテム以外のアイテムを選択して「追加」をクリックすると、選択したアイテムが維持されていることに注意してください。したがって、ターゲットリストアイテムの管理にはもう少し外科的である必要があります。

多分それは助けになるか、多分私は要点を逃した。

于 2011-12-05T19:36:30.380 に答える
0

現在選択されているアイテム/選択の値を変数に設定し、操作を実行して、最後に値を選択に再選択します。

于 2011-12-03T20:44:12.830 に答える
0

あなたが何を求めているのかまだ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>
于 2011-12-06T21:49:37.927 に答える
0

さて、不器用ではないにしても、解決策への実行可能なアプローチがあると思います。追加されたオプションは常にリストの最後にあるため、トリッキーな部分は元のリストに値を追加することではありません。選択オプションを削除すると、現在の selectedIndex のインデックスが変更されるため、問題が発生します。Mac で Google Chrome を使用してテストしましたが、エラーは発生しませんでした。ソリューションにどのようにアプローチしたかを示すために、コードにコメントを付けました。

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

元の選択リストの末尾に追加するのではなく、現在の selectedIndex の後にオプションを挿入できるように、コードを変更する余地は十分にあります。理論的には、複数選択リスト/メニューも同様に機能するはずです。あなたに持っています。

ここにいる天才の 1 人が、私のコードよりもクリーンできれいなコードでこれと同じことを実行できると確信しています。私の元の質問を確認してコメントしてくれたすべての人に感謝します! 乾杯。

于 2011-12-05T19:07:09.003 に答える