<select >
<option value="something">something</option>
<option value="something_else">something else</option>
</select>
<input type="text" >
So that when user inputs something, only options with value matching the input will show.
This question is related to
javascript
jquery
dom
You can use select2 plugin for creating such a filter. With this lot's of coding work can be avoided. You can grab the plugin from https://select2.github.io/
This plugin is much simple to apply and even advanced work can be easily done with it. :)
using Aaron's answer, this can be the short & easiest solution:
function filterSelectList(selectListId, filterId)
{
var filter = $("#" + filterId).val().toUpperCase();
$("#" + selectListId + " option").each(function(i){
if ($(this).text.toUpperCase().includes(filter))
$(this).css("display", "block");
else
$(this).css("display", "none");
});
};
Just a minor modification to the excellent answer above by Lessan Vaezi. I ran into a situation where I needed to include attributes in my option entries. The original implementation loses any tag attributes. This version of the above answer preserves the option tag attributes:
jQuery.fn.filterByText = function(textbox) {
return this.each(function() {
var select = this;
var options = [];
$(select).find('option').each(function() {
options.push({
value: $(this).val(),
text: $(this).text(),
attrs: this.attributes, // Preserve attributes.
});
});
$(select).data('options', options);
$(textbox).bind('change keyup', function() {
var options = $(select).empty().data('options');
var search = $.trim($(this).val());
var regex = new RegExp(search, "gi");
$.each(options, function(i) {
var option = options[i];
if (option.text.match(regex) !== null) {
var new_option = $('<option>').text(option.text).val(option.value);
if (option.attrs) // Add old element options to new entry
{
$.each(option.attrs, function () {
$(new_option).attr(this.name, this.value);
});
}
$(select).append(new_option);
}
});
});
});
};
A much simpler way nowadays is to use the jquery filter() as follows:
var options = $('select option');
var query = $('input').val();
options.filter(function() {
$(this).toggle($(this).val().toLowerCase().indexOf(query) > -1);
});
This is a simple solution where you clone the lists options and keep them in an object for recovery later. The scripts cleans out the list and add only the options that contains the input text. This should also work cross browser. I got some help from this post: https://stackoverflow.com/a/5748709/542141
Html
<input id="search_input" placeholder="Type to filter">
<select id="theList" class="List" multiple="multiple">
or razor
@Html.ListBoxFor(g => g.SelectedItem, Model.items, new { @class = "List", @id = "theList" })
script
<script type="text/javascript">
$(document).ready(function () {
//copy options
var options = $('#theList option').clone();
//react on keyup in textbox
$('#search_input').keyup(function () {
var val = $(this).val();
$('#theList').empty();
//take only the options containing your filter text or all if empty
options.filter(function (idx, el) {
return val === '' || $(el).text().indexOf(val) >= 0;
}).appendTo('#theList');//add it to list
});
});
</script>
Slightly different to all the other but I think this is the most simple:
$(document).ready(function(){
var $this, i, filter,
$input = $('#my_other_id'),
$options = $('#my_id').find('option');
$input.keyup(function(){
filter = $(this).val();
i = 1;
$options.each(function(){
$this = $(this);
$this.removeAttr('selected');
if ($this.text().indexOf(filter) != -1) {
$this.show();
if(i == 1){
$this.attr('selected', 'selected');
}
i++;
} else {
$this.hide();
}
});
});
});
I had a similar problem to this, so I altered the accepted answer to make a more generic version of the function. I thought I'd leave it here.
var filterSelectOptions = function($select, callback) {
var options = null,
dataOptions = $select.data('options');
if (typeof dataOptions === 'undefined') {
options = [];
$select.children('option').each(function() {
var $this = $(this);
options.push({value: $this.val(), text: $this.text()});
});
$select.data('options', options);
} else {
options = dataOptions;
}
$select.empty();
$.each(options, function(i) {
var option = options[i];
if(callback(option)) {
$select.append(
$('<option/>').text(option.text).val(option.value)
);
}
});
};
I'm not sure why you have more than one option with the same value, but this works
$(document).ready(function() {_x000D_
$('input').change(function() {_x000D_
var filter = $(this).val();_x000D_
$('option').each(function() {_x000D_
if ($(this).val() == filter) {_x000D_
$(this).show();_x000D_
} else {_x000D_
$(this).hide();_x000D_
}_x000D_
$('select').val(filter);_x000D_
})_x000D_
})_x000D_
})
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<select>_x000D_
<option value="something1">something1</option>_x000D_
<option value="something1">something1</option>_x000D_
<option value="something2">something2</option>_x000D_
<option value="something2">something2</option>_x000D_
<option value="something2">something2</option>_x000D_
<option value="something3">something3</option>_x000D_
<option value="something3">something3</option>_x000D_
<option value="something3">something3</option>_x000D_
</select>_x000D_
<input type="text" placeholder="something1">
_x000D_
Much simpler code then most of the other solutions. Look for the text (case insensitive) and use CSS to hide/show the contents. Much better than storing a copy of the data.
Pass into this method the id of the select box, and id of the input containing a filter.
function FilterSelectList(selectListId, filterId)
{
var filter = $("#" + filterId).val();
filter = filter.toUpperCase();
var options = $("#" + selectListId + " option");
for (var i = 0; i < options.length; i++)
{
if (options[i].text.toUpperCase().indexOf(filter) < 0)
$(options[i]).css("display", "none");
else
$(options[i]).css("display", "block");
}
};
Update Lessan's answer to also keep the attributes of the options.
This is my first time answering on Stack Overflow so not sure if I should edit his answer or create my own.
jQuery.fn.allAttr = function() {
var a, aLength, attributes, map;
if (!this[0]) return null;
if (arguments.length === 0) {
map = {};
attributes = this[0].attributes;
aLength = attributes.length;
for (a = 0; a < aLength; a++) {
map[attributes[a].name.toLowerCase()] = attributes[a].value;
}
return map;
} else {
for (var propin arguments[0]) {
$(this[0]).attr(prop, arguments[0][prop]);
}
return this[0];
}
};
jQuery.fn.filterByText = function(textbox) {
return this.each(function() {
var select = this;
var options = [];
$(select).find('option').each(function() {
options.push({ value: $(this).val(),
text: $(this).text(),
allAttr: $(this).allAttr() });
});
$(select).data('options', options);
$(textbox).bind('change keyup', function() {
var search = $.trim($(this).val());
var regex = new RegExp(search, "gi");
$.each($(select).empty().data('options'), function(i, option) {
if (option.text.match(regex) !== null) {
$(select).append(
$('<option>').text(option.text)
.val(option.value)
.allAttr(option.allAttr)
);
}
});
});
});
};
Example HTML:
//jQuery extension method:_x000D_
jQuery.fn.filterByText = function(textbox) {_x000D_
return this.each(function() {_x000D_
var select = this;_x000D_
var options = [];_x000D_
$(select).find('option').each(function() {_x000D_
options.push({_x000D_
value: $(this).val(),_x000D_
text: $(this).text()_x000D_
});_x000D_
});_x000D_
$(select).data('options', options);_x000D_
_x000D_
$(textbox).bind('change keyup', function() {_x000D_
var options = $(select).empty().data('options');_x000D_
var search = $.trim($(this).val());_x000D_
var regex = new RegExp(search, "gi");_x000D_
_x000D_
$.each(options, function(i) {_x000D_
var option = options[i];_x000D_
if (option.text.match(regex) !== null) {_x000D_
$(select).append(_x000D_
$('<option>').text(option.text).val(option.value)_x000D_
);_x000D_
}_x000D_
});_x000D_
});_x000D_
});_x000D_
};_x000D_
_x000D_
// You could use it like this:_x000D_
_x000D_
$(function() {_x000D_
$('select').filterByText($('input'));_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<select>_x000D_
<option value="hello">hello</option>_x000D_
<option value="world">world</option>_x000D_
<option value="lorem">lorem</option>_x000D_
<option value="ipsum">ipsum</option>_x000D_
<option value="lorem ipsum">lorem ipsum</option>_x000D_
</select>_x000D_
<input type="text">
_x000D_
Live demo here: http://www.lessanvaezi.com/filter-select-list-options/
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script language='javascript'>
jQuery.fn.filterByText = function(textbox, selectSingleMatch) {
return this.each(function() {
var select = this;`enter code here`
var options = [];
$(select).find('option').each(function() {
options.push({value: $(this).val(), text: $(this).text()});
});
$(select).data('options', options);
$(textbox).bind('change keyup', function() {
var options = $(select).empty().scrollTop(0).data('options');
var search = $.trim($(this).val());
var regex = new RegExp(search,'gi');
$.each(options, function(i) {
var option = options[i];
if(option.text.match(regex) !== null) {
$(select).append(
$('<option>').text(option.text).val(option.value)
);
}
});
if (selectSingleMatch === true &&
$(select).children().length === 1) {
$(select).children().get(0).selected = true;
}
});
});
};
$(function() {
$('#selectorHtmlElement').filterByText($('#textboxFiltr2'), true);
});
</script>
Source: Stackoverflow.com