Отображение сообщения, когда фильтр jQuery ничего не возвращает

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

0
задан showdev 14 April 2019 в 05:31
поделиться

3 ответа

Вы можете создать переменную для подсчета совпадений.

$("button").click(function(){
var value = $(this).data('value').toUpperCase();
var count = 0;
$("div").filter(function(index) {

  if($(this).text().indexOf(value) > -1) count++;

  $(this).toggle($(this).text().indexOf(value) > -1)

  });
  if(count == 0) alert('Not match');
});

$("button").click(function(){
var value = $(this).data('value').toUpperCase();
var count = 0;
$("div").filter(function(index) {

  if($(this).text().indexOf(value) > -1) count++;
  
  $(this).toggle($(this).text().indexOf(value) > -1)
  
  });
  if(count == 0) alert('Not match');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>TEST1</div>
<div>example</div>
<div>test1</div>


<button data-value='test1'>example</button>

0
ответ дан Hien Nguyen 14 April 2019 в 05:31
поделиться

filter() возвращает значение. Проверьте, равна ли длина 1 или более.

$(".filter").click(function() {
  var value = $(this).text(); //Get the text of the button
  var result = $("div").hide().filter(function(i, o) { //Hide All and filter
    return $(o).text().includes(value); //Return true if the content of div contains text of the button
  }).show(); //Show all result


  if (result.length) { //Check the length of the result
    //Found match/es
    $(".msg").text('');
  } else {
    //No match
    $(".msg").text(`${value} not found`);
  }
});

$(".show-all").click(function() {
  $("div").show();
});
.msg {
  border: 1px solid black;
}

div {
  background-color: pink
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<span class="msg"></span>

<br /><br />

<div> apple </div>
<div> orange </div>
<div> rock melon</div>
<div> pineapple </div>
<div> pineapple pie</div>

<br /><br />

<button class="filter">example</button>
<button class="filter">pineapple</button>
<button class="filter">rock</button>

<br /><br />

<button class="show-all">Show all</button>

0
ответ дан Eddie 14 April 2019 в 05:31
поделиться

Вы используете filter() для переключения каждого элемента в зависимости от состояния, например, используете each() . Но одно из преимуществ filter() заключается в том, что вы можете вернуть уменьшенный выбор и сосчитать содержащиеся в нем элементы. Это значение может определять, должно ли отображаться сообщение «нет совпадения».

... метод .filter () создает новый объект jQuery из подмножества соответствующих элементов. Поставляемый селектор проверяется по каждому элементу; все элементы, соответствующие селектору, будут включены в результат. - фильтр () .

Для каждого элемента, если функция возвращает true (или «истинное» значение), элемент будет включен в отфильтрованный набор; в противном случае это будет исключено. - Использование функции фильтра

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

var $filtered = $items.filter(function() {
  return $(this).text().indexOf(value) > -1;
});

$items.toggle(false);
$filtered.toggle(true);

Это скрывает все элементы, а затем показывает только отфильтрованные элементы.
Вы можете даже рассмотреть некоторую анимацию затухания:

$items.hide(250);
$filtered.stop(true,false).show(250);

Затем вы можете сослаться на отфильтрованные выделения length .
Если оно равно нулю, покажите сообщение «not found»:

var hasMatches = $filtered.length;

if (hasMatches) {
  // there were matches.
} else {
  // no matches.
}

Вы также можете передать селектор в фильтр. Селектор jQuery :contains() выбирает «все элементы, которые содержат указанный текст», что делает хороший выбор.

Рабочий пример:

var $items = $('.item');
var $none = $('#none');
var fade = 250;

function filterContent() {

  // get word from value of clicked button.
  var word = this.value;

  // hide items; filter; show filtered; count matches
  var hasMatches = $items
    .hide(fade)
    .filter(':contains(' + word + ')')
    .stop(true, false)
    .show(fade)
    .length;

  // if no matches, show message.
  if (hasMatches) {
    $none.hide(fade);
  } else {
    $none.show(fade);
  }

}

$('button').on('click', filterContent);
#none {
  display: none;
  color: darkred;
}

#buttons {
  margin: 1em 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="item">Here is some text.</div>
<div class="item">Here is some other text.</div>
<div class="item">Here is some other different text.</div>
<div class="item">Here is something else.</div>
<div class="item">Here is some additional text.</div>

<div id="none">No matches found.</div>

<nav id="buttons">
  <button type="button" value="">all</button>
  <button type="button" value="text">text</button>
  <button type="button" value="other">other</button>
  <button type="button" value="additional">additional</button>
  <button type="button" value="bazooka">bazooka</button>
</nav>

<час>

] Другой способ:

Если вы предпочитаете, вы можете переключаться внутри фильтра, пока вы все еще возвращаете логическое состояние из функции. Я предлагаю сделать отдельную функцию для перехода на фильтр. В этом случае toggleItem() определяет состояние элемента (соответствует или не соответствует), переключает элемент в соответствии с этим состоянием и возвращает состояние.

var $items = $('.item');
var $none = $('#none');

function toggleItem(word) {
  return function(k, el) {
    var $item = $(el);
    var state = $item.text().indexOf(word) > -1;
    $item.toggle(state);
    return state;
  }
}

function filterContent() {

  // get word from value of clicked button.
  var word = this.value;

  // filter while toggling and count result.
  var hasMatches = $items
    .filter(toggleItem(word))
    .length;

  // if no matches, show message.
  $none.toggle(!hasMatches);

}

$('button').on('click', filterContent);
#none {
  display: none;
  color: darkred;
}

#buttons {
  margin: 1em 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="item">Here is some text.</div>
<div class="item">Here is some other text.</div>
<div class="item">Here is some other different text.</div>
<div class="item">Here is something else.</div>
<div class="item">Here is some additional text.</div>

<div id="none">No matches found.</div>

<div id="buttons">
  <button type="button" value="">all</button>
  <button type="button" value="text">text</button>
  <button type="button" value="other">other</button>
  <button type="button" value="additional">additional</button>
  <button type="button" value="bazooka">bazooka</button>
</div>

На мой взгляд, это немного сложнее для чтения и не так ясно, как прикованная цепью , filter, show, length ", но это в некоторой степени вопрос стиля. Вы можете видеть, что есть много способов испечь этот пирог!

Этот довольно короткий и сладкий:

var $none = $("#none");
var $items = $(".item");

$("button").click(function() {

  var value = $(this).data('value');

  $items.each(function() {
    $(this).toggle($(this).text().indexOf(value) > -1);
  });

  $none.toggle(!$items.filter(':visible').length);

});
#none {
  display: none;
  color: darkred;
}

#buttons {
  margin: 1em 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="item">Here is some text.</div>
<div class="item">Here is some other text.</div>
<div class="item">Here is some other different text.</div>
<div class="item">Here is something else.</div>
<div class="item">Here is some additional text.</div>

<div id="none">No matches found.</div>

<nav id="buttons">
  <button type="button" data-value="">all</button>
  <button type="button" data-value="text">text</button>
  <button type="button" data-value="other">other</button>
  <button type="button" data-value="additional">additional</button>
  <button type="button" data-value="bazooka">bazooka</button>
</nav>

0
ответ дан showdev 14 April 2019 в 05:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: