2012-09-24 11 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> 

Ho bisogno di convertire dinamicamente questo in modo che le opzioni "Categoria" (qualsiasi cosa che non inizia con "voce") è un optgroup, avvolgendo whaterver viene dopo fino a quando l'opzione Categoria prossimo, per cui la suddetta sarebbe finire per assomigliare:Aggiunta optgroups utilizzando jQuery dinamicamente

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

Come posso iterare questo e cambiare i valori per acheive l'effetto desiderato utilizzando jQuery?

risposta

17

E 'abbastanza facile utilizzando 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

soluzione molto elegante! – vzwick

+0

superbo !! mi ha aiutato subito –

5

È possibile utilizzare filter() per abbinare i <option> elementi che diventeranno gruppi. Quindi, puoi scorrere su di loro e chiamare lo nextUntil() sullo stesso insieme di elementi per abbinare le opzioni successive (come nextUntil() si fermerà quando incontra un membro del set, vale a dire l'opzione successiva che dovrebbe diventare un gruppo).

Da lì, è possibile utilizzare wrapAll() nelle <option> elementi per creare il loro elemento <optgroup>, quindi chiamare remove() sull'elemento <option> che è diventato solo un gruppo. Qualcosa di simile:

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

È possibile visualizzare i risultati in this fiddle.

+0

Mi piace l'uso di wrapAll - Non ero sicuro di come usarlo se non sapessi in anticipo a quali elementi dovevano andare (ho visto un esempio in cui il numero di elementi da aggiungere ad un optgroup sono stati corretti). Molte grazie. – key2starz

+0

+1 questo approccio ha funzionato per me, tuttavia ha funzionato solo dopo aver eseguito un aggiornamento sul multiselect - $ ("# myElement"). Multiselect ('refresh'); quindi questo potrebbe salvare qualcun altro mezza giornata di grattarsi la testa –

2

mia realizzazione:

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

Demo: 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); 
}); 
Problemi correlati