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> 

Necesito convertir dinámicamente este modo que "categoría" Opciones (cualquier cosa que no comience por "elemento") es un optgroup, envolviendo whaterver viene después de él hasta la siguiente opción Categoría, lo que lo anterior podría terminar pareciéndose a:Adición optgroups utilizando jQuery dinámicamente

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

¿Cómo puedo iterar sobre esto y los valores de cambio a acheive el efecto deseado usando jQuery?

Respuesta

17

Es muy fácil de usar 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

solución muy elegante! – vzwick

+0

excelente !! ayudó de inmediato –

5

Puede utilizar filter() para que coincida con los <option> elementos que se convertirán en grupos. Luego, puede iterar sobre ellos y llamar al nextUntil() en el mismo conjunto de elementos para que coincida con las opciones subsiguientes (ya que nextUntil() se detendrá cuando encuentre un miembro del conjunto, es decir, la siguiente opción que debería convertirse en un grupo).

A partir de ahí, se puede utilizar en estos wrapAll()<option> elementos para crear su elemento <optgroup>, a continuación, llamar remove() en el elemento <option> que acaba de convertirse en un grupo. Algo así como:

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

Puede ver los resultados en this fiddle.

+0

Me gusta el uso de wrapAll - No estaba seguro de cómo usarlo si no sabía de antemano qué elementos iban a entrar (vi un ejemplo donde el número de elementos que se agregarán a un optgroup fueron arreglados). Muchas gracias. – key2starz

+0

+1 este enfoque funcionó para mí, sin embargo, solo funcionó después de hacer una actualización en el multiselect - $ ("# myElement"). Multiselect ('refresh'); así que esto podría salvar a alguien más medio día de rascarse la cabeza –

2

Mi aplicación:

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

Demostración: 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); 
}); 
Cuestiones relacionadas