Рассмотрим следующий код.
https://jsfiddle.net/Twisty/zvtymk1r/29/
HTML
<form action="/action_page.php">
<label for="fname">Find City</label>
<input type="text" id="textbox" name="textbox"><br><br>
<select name="myfiltercities" id="myfiltercities_id">
<option value=""></option>
<optgroup label="Alabama" data-abbr="AL">
<option value="123">Birmingham</option>
<option value="123">Huntsville</option>
</optgroup>
<optgroup label="Alaska" data-abbr="AK">
<option value="456">Anchorage</option>
<option value="789">Juneau</option>
<option value="135">Fairbanks</option>
</optgroup>
<optgroup label="Arizona" data-abbr="AZ">
<option value="198">Phoenix</option>
<option value="065">Tucson</option>
</optgroup>
<optgroup label="Arkansas" data-abbr="AR">
<option value="835">Little Rock</option>
</optgroup>
<optgroup label="California" data-abbr="CA">
<option value="402">Los Angeles</option>
</optgroup>
</select>
</form>
JavaScript
jQuery.fn.filterByText = function(textbox, selectSingleMatch) {
return this.each(function() {
var select = this;
$('#myfiltercities_id').hide().children().hide();
$(textbox).on("change keyup", function(e) {
$('#myfiltercities_id').hide().children().hide();
var search = $(this).val().trim().toLowerCase();
if (search.length >= 2) {
$('#myfiltercities_id').show();
$("optgroup", select).each(function(i, el) {
var label = $(el).attr("label").toLowerCase();
var abbr = $(el).data("abbr").toLowerCase();
if (search.length == 2) {
if (abbr == search) {
console.log(search, label, abbr);
$(el).show();
}
} else {
if (label.indexOf(search) >= 0) {
console.log(search, label, abbr);
$(el).show();
}
}
});
}
});
});
}
$(function() {
$('#myfiltercities_id').filterByText($('#textbox'), true);
$("select option").click(function() {
alert(this.value);
});
});
Сначала ваша HTML Структура не способствовала правильному поиску. Аббревиатура не коррелировала с результатами. Я переместил это в атрибут данных, связанный с городами.
Ваша функция поиска изначально была разработана для элементов Option и не подходит для групп. Также он повторно добавлял опции обратно к выбору. Это казалось слишком сложным.
Я считаю, что при фильтрации проще просто Скрыть все элементы, а затем Показать элементы, соответствующие фильтру. в зависимости от количества символов во входных данных мы можем искать аббревиатуру или полное название штата. На это легко взглянуть.
Таким образом, если пользователь будет искать "al"
, он получит Алабаму, но если затем продолжит поиск "ala"
, они найдут Алабаму и Аляску.