Seems like a pretty simple idea, but I can't figure out how to filter out option tags of the original select from the select2 dropdown.
Basically, this:
<select id="select">
<option class="car">Car 1</option>
<option class="plane">Plane 1</option>
</select>
$("#select").select2();
... should create a fake select with only the option tags with the class car
.
Seems like a pretty simple idea, but I can't figure out how to filter out option tags of the original select from the select2 dropdown.
Basically, this:
<select id="select">
<option class="car">Car 1</option>
<option class="plane">Plane 1</option>
</select>
$("#select").select2();
... should create a fake select with only the option tags with the class car
.
4 Answers
Reset to default 7It appears the OP found the answer at https://github.com/select2/select2/issues/1048.
The answer is to supply a matcher
function.
$("#select").select2({
matcher: function(term, text, option) {
return option.hasClass('car');
}
});
jsfiddle
Just to keep this question up-to-date.. The proposed answer with the use of supplying the matcher
function is outdated. Since Select2 4.0.0 you need to use a wrapper with the matcher
:
function matchStart (term, text) {
if (text.toUpperCase().indexOf(term.toUpperCase()) == 0) {
return true;
}
return false;
}
$.fn.select2.amd.require(['select2/compat/matcher'], function (oldMatcher) {
$(".js-example-matcher-start").select2({
matcher: oldMatcher(matchStart)
})
});
For ME, this didn't work. I don't know why. But I've found a work-around for this. Apparently, with Select2 you can also supply a format function to the .select2()
method for each option
or element in the select. For example, when you want to prepend each element with an icon or something like this. Turns out that the element won't be shown in the dropdown if you return null
in the format function, like this:
function formatState(state) {
if (!state.id) { return state.text; }
if (state.disabled) { return null; }
var $state = $('<span>'.concat(state.text).concat("</span>"));
return $state;
}
$('#myDropdown').select2({
templateResult: formatState
});
This worked for me immediately. Perhaps it could help any of you with current implementations.
You should use the "disabled" property of the option. If you want to filter it out, set it to "disabled". This greys it out in the select2. Alternatively you can use the CSS class to hide it rather grey it out.
I have been struggling with problem for some time, and posted my own similar question. The problem with the matcher solution provided above is that the matcher is used to match a search, while just opening the dropdown would simply match all the list and therefore show everything which isn't quite satisfactory.
After an initial buggy solution, I finally resorted to 'destroy'ing the select2 and rebuilding it after filtering the select. Here is the solution to the question using this approach,
//assuming you are usign jquery...
//keep a non-filtered copy of the original select
var $clonedSelect = $('select#select').clone();
$.fn.filterSelect2 = function(class=''){
if( $(this).is('select') ){
$(this).select2('destroy');
$(this).empty();
$(this).append( $('option.'+class, $clonedSelect).clone() );
$(this).select2();
}
return $(this);
}
$('select#select').filterSelect2('car'); //will create a select2 with only the car class options.
I haven't tested this, but I have used a similar logic for a more complex case in a recent project and found it to work very nicely.