2012-09-24 68 views
9
<select id="myElement" multiple="multiple"> 
    <option value="1">Category Type</option> 
    <option value="158">itemOne</option> 
    <option value="157">itemTwo</option> 
    <option value="7">My Type</option> 
    <option value="20">itemThree</option> 
    <option value="21">itemFour</option> 
    <option value="22">itemFive</option> 
    <option value="8">Category Yet Another</option> 
    <option value="31">itemCheese</option> 
    <option value="32">itemBrain</option> 
</select> 

我需要動態地將其轉換爲使「Category」選項(不以「item」開頭的任何內容)成爲optgroup,並將whaterver包含在下一個Category選項之後,所以上面最終會看起來像這樣:使用jQuery動態添加optgroup

<select id="myElement" multiple="multiple"> 
    <optGroup label="Category Type"> 
    <option value="158">One</option> 
    <option value="157">Two</option> 
    </optGroup> 
    <optGroup label="My Type"> 
    <option value="20">Three</option> 
    <option value="21">Four</option> 
    <option value="22">Five</option> 
    </optGroup> 
    <optGroup label="Category Yet Another"> 
    <option value="31">Cheese</option> 
    <option value="32">Brain</option> 
    </optGroup> 
</select> 

我該如何迭代這一點,並更改值以達到使用jQuery所需的效果?

回答

17

它使用jQuery非常簡單:

http://jsfiddle.net/mGmXq/

$(document).ready(function() { 
    var $cont = $('select'); 
    $('option').each(function() { 
     if ($(this).text().indexOf('item') !== 0) { 
      $('<optGroup/>').attr('label', $(this).text()).appendTo($cont); 
      $(this).remove(); 
     } else { 
      $cont.find('optGroup').last().append($(this)); 
      $(this).text($(this).text().substr(4)); 
     } 
    }); 
});​ 
+1

相當完美的解決方案! – vzwick

+0

精湛!立即幫助 –

5

您可以使用filter()匹配<option>元素,將成爲集團。然後,您可以遍歷它們並在同一元素集上調用nextUntil()以匹配後續選項(因爲nextUntil()在遇到集合的成員時即停止,即應該成爲組的下一個選項)。

從那裏,你可以使用wrapAll()這些<option>元素,創造自己的<optgroup>元素,那麼<option>元素剛剛成爲一組上調用remove()。例如:

var $groups = $("#myElement option").filter(function() { 
    return $(this).text().indexOf("item") != 0; 
}); 
$groups.each(function() { 
    var $this = $(this); 
    $this.nextUntil($groups).wrapAll($("<optgroup>", { 
     label: $this.text() 
    })).end().remove(); 
}); 

您可以在this fiddle中查看結果。

+0

我喜歡wrapAll的使用 - 我不確定如何使用它,如果我事先不知道哪些元素將要進入(我看到一個示例,其中要添加到optgroup被固定)。非常感謝。 – key2starz

+0

+1此方法適用於我,但它只在對multiselect進行刷新後才起作用 - $(「#myElement」)。multiselect('refresh');所以這可能會挽救別人半天的頭部劃傷 –

2

我的實現:

$(function(){ 
    var target = $('#target'), 
     optGroup; 

    function strStartsWith(str, prefix) { 
     return str.indexOf(prefix) === 0; 
    } 

    $('#myElement').find('option').each(function(){ 
     var elm = $(this).clone(); 
     if(strStartsWith(elm.text(), 'item')) 
     { 
      elm.text(elm.text().substr(4)); 
      if(optGroup) optGroup.append(elm); 
     } 
     else 
     { 
      optGroup = $('<optgroup>').attr('label', elm.text()); 
      target.append(optGroup); 
     } 
    }); 
}); 

演示:http://jsfiddle.net/HUHRz/1/

1
$.each(data, function() { 

    if (prevGroupName.indexOf(this.Group.Name) == -1) { 
     $prevGroup = $('<optgroup />').prop('label', this.Group.Name).appendTo('#ConfigurationId'); 
    } else { 
     $prevGroup = $("optgroup[label='" + this.Group.Name + "']"); 
    } 
    $("<option />").val(this.Value).text(this.Text).appendTo($prevGroup); 
    prevGroupName.push(this.Group.Name); 
});