2012-09-24 3 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이고 다음 Category 옵션까지 오는 것을 줄이기 위해 동적으로 변환해야합니다. 그래서 위처럼 보이는 끝낼 것 :jQuery를 사용하여 동적으로 optgroup 추가하기

내가 jQuery를 사용하여 원하는 효과를 acheive이 변경 값을 반복 할 수 있습니까
<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> 

?

답변

17

그것은 jQuery를 사용하여 매우 쉽게 : 당신은 그룹이 될 것이다 <option> 요소에 맞게 filter()을 사용할 수 있습니다

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

. 그런 다음 해당 항목을 반복하고 후속 옵션과 일치하도록 설정된 동일한 요소에서 nextUntil()을 호출 할 수 있습니다 (집합 구성원 (예 : 그룹이되어야하는 다음 옵션)을 만날 때 nextUntil()이 중지됨). 거기에서

, 당신은, 자신의 <optgroup> 요소를 생성 단지 그룹이 된 <option> 요소에 remove()를 호출이 <option> 요소에 wrapAll()를 사용할 수 있습니다. 예 :

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

나는 wrap의 사용을 좋아합니다 .All - 어떤 요소가 들어갈 지 미리 알지 못하면 어떻게 사용하는지 잘 모르겠습니다. (예를 들어, 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); 
}); 
관련 문제