2011-12-03 14 views
4

我有一個表單UI,其中幾個部分需要重複的HTML選擇列表從一個動態可更新的選擇列表動態更新。使用JavaScript和JQuery,如何維護動態更新的HTML選擇元素的選定狀態?

動態可更新列表工作得很好,因爲可以即時添加和刪除新選項。然後我可以使用JQuery .find()將這個更新傳播到每個重複列表中。我甚至添加了一些邏輯來維護原始選擇列表的當前選定索引。

我無法做的是維護每個重複選擇列表的選定狀態,因爲新選項將從原始選擇列表中添加並刪除。由於對原始選擇列表的每次更新都會遍歷每個重複選擇列表,因此它們會丟失其當前選定的選項索引。

下面是一個例子我conundrum-- *編輯 - 我會鼓勵你去嘗試和執行我下面提供的代碼和前申請你的理論建議的解決方案,因爲沒有的建議到目前爲止都有效。我相信你會發現這個問題一個很好的協議棘手比你可能會認爲,在第一種:

<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的),因爲此方法需要一般地應用於整個文檔中的其他動態創建的選擇列表。

在此先感謝!

+0

您可以選擇先用'$選擇( 「重複選擇:第一」)' ,如:'$(「副本中進行選擇:第一「).append('

+0

您可以將您的代碼(在最近的表單中,您遇到問題)發佈爲[jsfiddle](http:// jsfiddle .net /)或許?它會加快調查這個問題並幫助其他人改進它。 – Tadeck

+0

這裏是我通過jsFiddle的可行解決方案: http://jsfiddle.net/tMJ29/ – lincolnberryiii

回答

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

以下是您在jsFiddle上的解決方案:http://jsfiddle.net/x7ZbM/ 作品廣告!正如你所看到的,不管原始列表如何操作(添加/刪除),每個副本的selectedIndex都會保留。 對不起,如果我沒有在我原來的問題更清楚。 謝謝大家! – lincolnberryiii

0

只需將當前選中的項目/值選擇爲某個變量,然後執行您的操作,最後 將該值重新選擇到該選擇。

+0

我試過這個無濟於事。由於列表大小動態變化,所選選項的selectedIndex不再適用於新列表。不過,這給了我一個主意。謝謝! – lincolnberryiii

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,而不是附加到原始選擇列表的末尾插入。理論上,多選列表/菜單也應該可以工作。在你身邊。

我敢肯定,這裏的天才之一將能夠用比我的更乾淨,更漂亮的代碼來做同樣的事情。感謝所有對我的原始問題進行評論和評論的人!乾杯。

0

如果您可以重置一點,我認爲問題在於您將選擇列表的HTML設置爲另一個列表的HTML。瀏覽器可能不會嘗試保留當前選定的項目,如果所有的底層html被更改。

所以,我想你可能會嘗試做的是明確地將選項元素添加到目標列表。

試試這個jsfiddle。如果您選擇默認第一項以外的項目,然後單擊「添加」,請注意所選項目被保留。所以你需要在管理目標列表項目時多一點手術。

也許這會幫助或者我錯過了這一點。

+0

我在jsFiddle上的可行解決方案:http://jsfiddle.net/tMJ29/ – lincolnberryiii

相關問題