Условный оператор jQuery между trim.().split() и ‘точное совпадение’

#jquery

#jquery

Вопрос:

У меня есть функция jQuery, которая проверяет поле ввода и сравнивает его с группой списка. Если символы / слова найдены в элементе списка, он покажет только те элементы списка, которые содержат точное совпадение. Я использую trim().split() для обнаружения более одного слова / фразы.

Вот мой код:

 $('#box').keyup(function() {
  var valThis = $(this).val().toLowerCase();
  if (valThis == "") {
    $('.filterlist>li').show();
  } else {
    var subValues = valThis.trim().split(', ');
    $('.filterlist>li').each(function () {
      var node = $(this);
      var text = node.text().toLowerCase();  
      if (subValues.some(function (word) {
        return text.indexOf(word) !== -1;
      })) {
        node.show();  
      }
      else {
        node.hide();
      }
    });
  };
});
  
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="box" type="text" placeholder="Search">

<ul class="filterlist" style="list-style:none;">
  <li>1. red</li>
  <li>2. blue</li>
  <li>3. red blue yellow</li>
  <li>4. blue red yellow</li>
  <li>5. red yellow</li>
  <li>6. red green</li>
</ul>
  

Это отлично работает, если вы вводите «красный, желтый», все элементы, содержащие любое слово, показывают только элементы списка, содержащие эти слова, т. е. Все элементы будут отображаться, за исключением элемента «2», поскольку он имеет только «синий».
С другой стороны, если вы введете ‘red yellow’, он вернет только элементы ‘4’ и ‘5’ из-за точного совпадения.

Однако мой вопрос в том, есть ли способ сохранить эту функцию, но каким-то образом добавить условие, которое позволило бы пользователю показывать элементы, содержащие только то, что вводится, но не обязательно точное совпадение? т.е. input = ‘red yellow’> списки: ‘3’, ‘4 ‘ и ‘5’ или input = ‘синий зеленый’> списки не отображаются.

Я пытался использовать селекторы ‘: contains()’ и ‘: not(: contains())’, но просто не могу разобраться в этом.

Любая помощь была бы очень признательна.

ОБНОВЛЕНО:Теперь добавляет входные значения в виде class / s в тег li.

 $('#box').keyup(function() {
  var valThis = $(this).val().toLowerCase();

  /* remove split character */
  var valClass = valThis.replace(',','');

  if (valThis == "") {
    $('.filterlist>li').show();
  } else {
    var subValues = valThis.trim().split(', ');
    $('.filterlist>li').each(function () {
      var node = $(this);
      var text = node.text().toLowerCase();  
      if (subValues.some(function (word) {
        return text.indexOf(word) !== -1;
      })) {
        node.show();
        $(this).removeClass().addClass(valClass);  
      }
      else {
        node.hide();
      }
    });
  };
});
  

Комментарии:

1. Возможно ли, что слова, которые вы ищете, могут быть помещены в li классы as? например <li class="red blue yellow">3. red blue yellow</li> ? Если это так, то достичь того, что вам нужно, становится намного, намного проще. Дайте мне знать, если это так, и я приведу вам пример того, как структурировать логику

2. позвольте мне быстро поиграть

3. Вот JSFiddle текущего сценария jsfiddle.net/5v1vx6de

4. @Rory McCrossan — смотрите Обновление, мне удается получить входное значение в виде классов

5. @Daniel спасибо за скрипку

Ответ №1:

Если вы можете добавить значения поиска в виде классов к li элементам, вы можете значительно упростить свою логику, выбрав элементы по классам.

Для этого просто удалите пробел в поисковом запросе и замените его на . . Попробуйте это:

 $('#box').keyup(function() {
  var searchTerm = $(this).val().toLowerCase();
  if (searchTerm == '') {
    $('.filterlist > li').show();
  } else {
    try {
      var selector = '.'   searchTerm.replace(/s /g, '.');
      $('.filterlist > li').hide().filter(selector).show();
    } catch(e) {
      // only to bury the error when a selector is built whilst the user is mid-typing
    }
  };
});  
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="box" type="text" placeholder="Search">

<ul class="filterlist" style="list-style:none;">
  <li class="red">1. red</li>
  <li class="blue">2. blue</li>
  <li class="red blue yellow">3. red blue yellow</li>
  <li class="blue red yellow">4. blue red yellow</li>
  <li class="red yellow">5. red yellow</li>
  <li class="red green">6. red green</li>
</ul>  

Обратите внимание, что try / catch требуется здесь только для предотвращения ошибок, которые могут возникнуть, когда поисковый запрос находится в процессе ввода, а сгенерированный селектор недействителен — например .red,. . Если вы изменили дизайн, чтобы использовать кнопку, вы потенциально можете удалить эту попытку / перехват.

Ответ №2:

Условие if в вашем решении необходимо изменить.

Вы можете найти измененный и рабочий код в скрипке ниже:

https://jsfiddle.net/9vhhvgb3/

Изменения
for(var i=0;i<subValues.length;i ){
if(text.indexOf(subValues[i]) > -1){
nodeToDisplay = true;
}else{
nodeToDisplay = false;
}
}
if(nodeToDisplay){
node.show();
}
else {
node.hide();
}

Комментарии:

1. почти понял, но что, если бы мы искали точное совпадение ‘red yellow’, в настоящее время все элементы будут отображаться с красным и желтым. Также только что заметил, что использование ‘, ‘ не показывает все элементы, т.Е. Синий, зеленый показывает только зеленые элементы