2009-09-19 9 views
27
<select > 
<option value="something">something</option> 
<option value="something_else">something else</option> 
</select> 
<input type="text" > 

Tak więc, gdy użytkownik wprowadzi coś, wyświetlone zostaną tylko opcje o wartości zgodnej z wejściem.Jak dynamiczne opcje filtrowania <select > z jQuery?

Odpowiedz

8

Nie jestem pewien, dlaczego masz więcej niż jedną opcję o tej samej wartości, ale to działa

$(document).ready(function() { 
 
    $('input').change(function() { 
 
    var filter = $(this).val(); 
 
    $('option').each(function() { 
 
     if ($(this).val() == filter) { 
 
     $(this).show(); 
 
     } else { 
 
     $(this).hide(); 
 
     } 
 
     $('select').val(filter); 
 
    }) 
 
    }) 
 
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<select> 
 
    <option value="something1">something1</option> 
 
    <option value="something1">something1</option> 
 
    <option value="something2">something2</option> 
 
    <option value="something2">something2</option> 
 
    <option value="something2">something2</option> 
 
    <option value="something3">something3</option> 
 
    <option value="something3">something3</option> 
 
    <option value="something3">something3</option> 
 
</select> 
 
<input type="text" placeholder="something1">

+3

starałem się realizować to, ale to nie może być krzyż przeglądarka zgodna http://stackoverflow.com/questions/1271503/hide-options-in-a-select-list-using-jquery – James

69

Przykład HTML:

//jQuery extension method: 
 
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() 
 
     }); 
 
    }); 
 
    $(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) { 
 
      $(select).append(
 
      $('<option>').text(option.text).val(option.value) 
 
     ); 
 
     } 
 
     }); 
 
    }); 
 
    }); 
 
}; 
 

 
// You could use it like this: 
 

 
$(function() { 
 
    $('select').filterByText($('input')); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<select> 
 
    <option value="hello">hello</option> 
 
    <option value="world">world</option> 
 
    <option value="lorem">lorem</option> 
 
    <option value="ipsum">ipsum</option> 
 
    <option value="lorem ipsum">lorem ipsum</option> 
 
</select> 
 
<input type="text">

Demo na żywo tutaj: http://www.lessanvaezi.com/filter-select-list-options/

+0

Dziękuję bardzo dużo za fragment. To pozwoliło mi zaoszczędzić mnóstwo czasu przy małym projekcie - działa jak czar! –

+0

To świetnie, ale w moim przypadku pole tekstowe filtru może zawierać tekst tuż po załadowaniu strony. Jak mogę zainicjować filtrowanie zaraz po załadowaniu strony? –

+0

Znaleziono! '$ ('input'). change();' –

3

Jest to proste rozwiązanie polegające na klonowaniu opcji list i przechowywaniu ich w obiekcie do późniejszego odzyskania. Skrypty czyści listę i dodaje tylko opcje, które zawierają tekst wejściowy. Powinno to również działać w przeglądarce krzyżowej. Mam jakąś pomoc z tego postu: https://stackoverflow.com/a/5748709/542141

HTML

<input id="search_input" placeholder="Type to filter"> 
<select id="theList" class="List" multiple="multiple"> 

lub brzytwa

@Html.ListBoxFor(g => g.SelectedItem, Model.items, new { @class = "List", @id = "theList" }) 

skrypt

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

Zaktualizuj odpowiedź Lessana, aby zachować atrybuty opcji.

To jest moja pierwsza odpowiedź na przepełnienie stosu, więc nie jestem pewien, czy powinienem edytować swoją odpowiedź, czy utworzyć własną.

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) 
     ); 
     } 
     }); 
    }); 
    }); 
}; 
+0

byłoby o wiele łatwiej ukryć te, których nie chcesz. – Dementic

5

Nieco różni się od wszystkich innych, ale myślę, że jest to najbardziej prosty:

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

}); 
+0

Mieszanka Mottie i Herskera –

0

Można użyć select2 plugin do tworzenia takiego filtra. Dzięki tej serii kodowania można uniknąć pracy. Możesz pobrać wtyczkę z https://select2.github.io/

Ta wtyczka jest łatwa do zastosowania, a nawet zaawansowaną pracę można z łatwością wykonać. :)

0

Miałem podobny problem z tym, więc zmieniłem zaakceptowaną odpowiedź, aby uzyskać bardziej ogólną wersję funkcji. Myślałem, że zostawię to tutaj.

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) 
      ); 
     } 
    }); 
}; 
0
<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> 
1

znacznie prostszy kod następnie większości innych rozwiązań. Poszukaj tekstu (bez rozróżniania wielkości liter) i użyj CSS, aby ukryć/pokazać zawartość. Znacznie lepsze niż przechowywanie kopii danych.

Należy podać w tej metodzie identyfikator pola wyboru, a id wejścia zawierającego filtr.

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"); 
    } 
}; 
Powiązane problemy