2014-12-29 2 views
1

Я создал небольшой плагин, который настраивает меню выбора. В этом выпадающем списке я должен реализовать функцию поиска. Однако я добавляю функциональность, но иногда она не дает правильного результата, например. если вы наберете «а» в поле ввода, то он должен показать результат, как указано ниже.test в javascript не работает согласно ожиданию

enter image description here

но мой плагин дает результат ниже. Он также заменяет букву верхнего регистра строчной буквой. Я пытаюсь решить это, но не мог понять, как это исправить. fiddle

enter image description here

searchItem: function() { 
    var patt = new RegExp(this.value, 'gi') 
    var val = this.value; 
    $('#options li').each(function() { 

     if (!patt.test($(this).text())) { 
      $(this).hide(); 
     } else { 
      $(this).show(); 
      apply.highlight.call(this, val); 
     } 
    }); 

    $('#options h2').each(function() { 
     if (!patt.test($('label', this).text())) { 
      $(this).hide(); 
     } else { 
      $(this).show(); 
      apply.highlight.call(this, val) 
     } 
    }); 

} 
+1

Если вы не возражаете, установив опечатку в свой код и отстудив ее :) –

+0

Вы хотите использовать совпадающий текст, а не введенное значение. – epascarello

ответ

2

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

Но .test() переместится в исходное положение для каждого матча (это для согласования последующих матчей на одной и той же строке)

Таким образом, вы должны создать новый объект RegExp для каждого элемента.(или использовать .match() и проверить его длину)

searchItem: function() { 
     var pattValue = this.value; 
     var val = this.value; 
     $('#options li').each(function() { 
      var patt = new RegExp(pattValue, 'gi'); 
      if (!patt.test($(this).text())) { 
       $(this).hide(); 
      } else { 
       $(this).show(); 
       apply.highlight.call(this, val); 
      } 
     }); 

     $('#options h2').each(function() { 
      var patt = new RegExp(pattValue, 'gi'); 
      if (!patt.test($('label', this).text())) { 
       $(this).hide(); 
      } else { 
       $(this).show(); 
       apply.highlight.call(this, val); 
      } 
     }); 
    } 

Для замены из символов на один вы, введенном использовать согласованный текст вместо пользователя, представленного один, вам нужно создать группу в RegExp и использовать этот захват, чтобы заменить матча

highlight: function (val) { 
     var nn = new RegExp('(' + (val||'^$') + ')', 'gi'); 
     var txt = $(this).find('label').text(); 
     txt = txt.replace(nn, "<span class='highlight'>$1</span>"); 
     $('label', this).html(txt) 
    } 

Наконец, вам нужно сбросить li variab ле при создании дополнительных устройств

Демонстрация наhttp://jsfiddle.net/b0rspd5e/

1

Это решить часть задачи (в нижнем регистре один плюс бесполезный интервал выделения) FIDDLE:

highlight: function (val) { 
    var nn = new RegExp('(' + val + ')', 'gi'), 
     txt = $(this).find('label').text(); 
    if (val.replace(/\s/g, '') == '') { 
     txt = txt.replace(new RegExp("<span class='highlight'>([\s\S]*?)</span>"),'$1'); 
     $('label', this).html(txt); 
    } 
    else{ 
    txt = txt.replace(nn, "<span class='highlight'>" + '$1' + "</span>"); 
    $('label', this).html(txt) 
    } 
} 

В основном я добавил () к regex, чтобы захватить группу а затем '$1', чтобы получить соответствующее значение.

EDIT
FIDDLE VERSION 2
Done также другая проблема (match способ, как предложил Габи ака Г. Petrioli), это мне потребовалось некоторое время из-за возвращаемого значения.
В принципе, если строка не возвращает никакого соответствия, var - null, поэтому if(nMatch) - достаточно.
возвращает true если var не null, undefined, NaN, empty string (""), 0 или false

searchItem: function() { 
    var patt = new RegExp(this.value, 'gi') 
    var val = this.value; 

    $('#options li').each(function() { 
     var nMatch= $(this).text().match(patt); 
     if(nMatch){ 
       $(this).show(); 
       apply.highlight.call(this, val) 
     } 
     else{ 
      $(this).hide(); 
     } 
    }) 

    $('#options h2').each(function() { 
     var nMatch= $('label', this).text().match(patt); 
     if(nMatch){ 
       $(this).show(); 
       apply.highlight.call(this, val) 
     } 
     else{ 
      $(this).hide(); 
     } 
    }) 

} 
1

Вы неоднократно вызывая .test метод того же регулярного выражения, которое было создано с g флагом. Когда вы это сделаете, последующий .test ing продолжается с lastIndex. Вот процесс согласования для строки a:

lastIndex String    Substring to match test() returns Position 
--------- ---------------- ------------------ -------------- -------- 
     0 " Volvo"   " Volvo"    false 
     0 " Saab"    " Saab"    true      2 
     3 " Volvo"   "lvo"     false 
     0 " Saab"    " Saab"    true      2 
     3 " Mercedes"   "rcedes"    false 
     0 " Audi"    " Audi"    true      1 
     2 " All Resident"  "ll Resident"   false 
     0 " All Comercial" " All Comercial"  true      1 

Это объясняет, почему заголовок «Все Resident» не отображается. Решение состоит в том, чтобы удалить флаг g, так как вы хотите протестировать каждую строку только один раз.

+0

Спасибо, я это лучшее объяснение ответа, который я когда-либо видел – Carlos

Смежные вопросы