Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Список SELECT с фильтрацией. помогите! (https://javascript.ru/forum/jquery/45890-spisok-select-s-filtraciejj-pomogite.html)

Pedro Garciya Lopez 19.03.2014 19:23

Список SELECT с фильтрацией. помогите!
 
Задача сделать список со строкой фильтрации сверху. Чтобы при вводе первых символов, элементы списка не содержащие этих символов скрывались, а если вообще подходящих элементов нет, список блокируется и в нем появляется строка "совпадений не найдено".

это работает, но только в mozilla. chrome и opera не скрывают элементы. почему?!

еще хотелось бы чтобы в отфильтрованном списке выделялся первый элемент, вот с этим полная беда даже в mozille, хотя на первый взгляд может показаться что работает, если ввести букву П, все города кроме Пензы скоются, и Пенза выделится, но если потом стереть П, ввести Ж, тоже самое произойдет с Житомером, теперь стираем Ж, пробуем опять П, Пенза отфильтруется но уже не выделяется ...

голова дымится, помогите разобраться, что делаю не так?

ниже привожу код, и вот "рабочий" пример на JSfiddle http://jsfiddle.net/macmacins/wb5EF/4/

<input style="display: block" id="Filter">
<select id="cityList" size="8">
    <option>Брянск</option>
    <option>Житомер</option>
    <option>Пенза</option>
    <option>Бердянск</option>    
</select>


$("#Filter").keyup(function()
{
    var search_str = this.value.toLowerCase();
    var conc = 0;

    if (($("#cityList").attr("disabled")=="disabled"))
    {
        $("#cityList option[value='-1']").remove();
        $("#cityList").attr("disabled", false);
    }

    $("#cityList option").each(function()
    {
        if (this.text.toLowerCase().indexOf(search_str)==0)
        {
            $(this).toggle(true);
        }
        else
        {
            $(this).toggle(false);
            conc ++;
        }
    });

    if (conc == $("#cityList option").size())
    {
        $("#cityList").append($('<option value="-1">Совпадейний не найдено</option>'));
        $("#cityList").attr("disabled", true);
    }
    
    //здесь пытаюсь выделять первый элемент видимого списка
    $("#cityList :visible:first").attr("selected", "selected");
})

рони 20.03.2014 02:02

Pedro Garciya Lopez,
:write:
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title> - jsFiddle demo by macmacins</title>
  <script type='text/javascript' src='http://code.jquery.com/jquery-1.9.1.js'></script>
<script>
$(window).load(function(){
var ops = $("#cityList option");

$("#Filter").on('input',function()
{
    var search_str = this.value.toLowerCase(), conc;
    $("#cityList option").remove();
    ops.each(function(indx, element){
         this.text.toLowerCase().indexOf(search_str)==0 && ($("#cityList").append($(this)))
          });
    conc = !$("#cityList option").size()
    conc && $("#cityList").append($('<option value="-1">Совпадейний не найдено</option>'));
    $("#cityList").prop("disabled", conc);
    $("#cityList :selected").prop("selected", false);
    $("#cityList option:first").prop("selected", true);
})
});
</script>
</head>
<body>
  <input style="display: block" id="Filter">
<select id="cityList" size="8">
    <option>Брянск</option>
    <option>Житомер</option>
    <option>Пенза</option>
    <option>Бердянск</option>
</select>
</body>
</html>

Pedro Garciya Lopez 20.03.2014 12:44

Рони, спасибо за ответ!

Ваш вариант превосходно работает в Chrome, но вот в Mozilla с выделением первого из отфильтрованных та же беда.

Наглядно эту беду можно увидеть выполнив следующий алгоритм:
1. фильтруем по "Б"
2. потом по "Бе"
до этого момента все работает как надо
3. теперь стираем "е" и оставляем "Б"
но выделенным остается по прежнему Бердянск
4. стираем все символы, отображается весь список, но выделенным остается не первый элемент, а по прежнему Бердянск
5. фильтруем по "Ж", выделяется Житомер, стирам "Ж", опять выделяется Бердянск
6. снова фильтруем по "Ж", Житомер отфильтровывается но уже не выделяется

ну и такая свистопляска продолжается до обновления страницы ...

сейчас проверил еще в Opera, Safari и IE:
в Opera работает идеально, как и в Chrome
в Safari если фильтровать по "Б", потом по "Бе" то выделяются сразу два элемента
ну а IE делает вид, что вообще ничего не происходит :)

видимо надо держать весь список в массиве, нужные элементы отфильтровывать в другой массив и его просто отдавать в Select выделяя первый, ибо все браузеры работают с Select'ом по разному.

рони 20.03.2014 13:24

Pedro Garciya Lopez,
исправил

Pedro Garciya Lopez 20.03.2014 15:09

Большое человеческое спасибо!

Так действительно работает везде, забыл о том что атрибуты и свойства - разные вещи.

я только начинаю осваивать jquery, и буду вам очень благодарен, если ответите еще на пару вопросов, это мне очень поможет в осмыслении :)
вопоса три, и они комментами к строчкам, которые мне не понятны:
<!DOCTYPE html>
	<html>
	<head>
	  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
	  <title> - jsFiddle demo by macmacins</title>
	  <script type='text/javascript' src='http://code.jquery.com/jquery-1.9.1.js'></script>
	<script>
		
	$(window).load(function(){
	// чем отличается от $(document).ready(function() ?
	
	var ops = $("#cityList option");
	 
	$("#Filter").on('input',function()
	{
	    var search_str = this.value.toLowerCase(), conc;
		
	    $("#cityList option").remove();
	    ops.each(function(indx, element){
		// не понял для чего в фунции описаны вот эти параметры (indx, element)

	         this.text.toLowerCase().indexOf(search_str)==0 && ($("#cityList").append($(this)))
			 // эта строка эквивалентна вот этой:
			 // if (this.text.toLowerCase().indexOf(search_str)==0) $("#cityList").append($(this))
			 // ?? и почему так работает? :)
			 
	    });
		
	    conc = !$("#cityList option").size();
	    conc && $("#cityList").append($('<option value="-1">Совпадейний не найдено</option>'));
	    
		$("#cityList").prop("disabled", conc);
	    $("#cityList :selected").prop("selected", false);
	    $("#cityList option:first").prop("selected", true);
	})
	});
	</script>
	</head>
	<body>
	  <input style="display: block" id="Filter">
	<select id="cityList" size="8">
	    <option>Брянск</option>
	    <option>Житомер</option>
	    <option>Пенза</option>
	    <option>Бердянск</option>
	</select>
	</body>
	</html>


еще раз большое спасибо!

рони 20.03.2014 15:23

Цитата:

Сообщение от Pedro Garciya Lopez
// чем отличается от $(document).ready(function() ?

тем что кроме html ждёт загрузку всего документа: картинки и прочее
Цитата:

Сообщение от Pedro Garciya Lopez
// не понял для чего в фунции описаны вот эти параметры (indx, element)

осталось от шаблона - в данном случае ненужны
Цитата:

Сообщение от Pedro Garciya Lopez
// эта строка эквивалентна вот этой:

да
если первый операнд false второй неисполняется

Pedro Garciya Lopez 20.03.2014 15:26

Спасибо! помогли разобраться, все предельно ясно.


Часовой пояс GMT +3, время: 21:50.