#jquery #search #criteria
#jquery #Поиск #критерии
Вопрос:
Несколько критериев поиска в списке
У меня есть список, как показано ниже
<ul>
<li>
<dl class="p_list1">
<dd id="name">
<b>Car</b></dd>
<dd id="company">
Honda, Hyundai, Toyota, Suzuki</dd>
</dl>
</li>
<li>
<dl class="p_list2">
<dd id="name">
<b>Bike</b></dd>
<dd id="company">
Honda, Yamaha, Suzuki</dd>
</dl>
</li>
<li>
<dl class="p_list3">
<dd id="name">
<b>Truck</b></dd>
<dd id="company">
Tata, Volvo, Mahindra</dd>
</dl>
</li>
</ul>
Я использую два текстовых поля txtName и txtCompany для поиска в этом списке.
На основе одного значения текстового поля или обоих значений текстового поля мне нужно отобразить и скрыть список.
- Если пользователь выполняет поиск в txtName, например «c», он должен показывать элементы 1 и 3. (txtCompany пуст)
- Если пользовательский поиск в txtcompany похож на «Hon», он должен отображать первый и второй список. (txtname пусто)
- Если txtName похоже на «c» и поиск пользователя в txtCompany, то он должен выполнять поиск из списка с элементами 1-го и 3-го
Я использовал ниже jquery
(
function ($) {
jQuery.expr[':'].Contains = function (a, i, m) {
return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
};
function listFilter(list) {
$('#txtName').change(function () {
var filter = $(this).val(); if (filter) { $(list).find("dd[id='name']:not(:Contains(" filter "))").parent().parent().slideUp(); $(list).find("dd[id='name']:Contains(" filter ")").parent().parent().slideDown(); }
else
{ $(list).find("li").slideDown(); }
return false;
}
).keyup(function () { $(this).change(); });
$('#txtCompany').change(function () {
var filter = $(this).val(); if (filter) { $(list).find("dd[id='company']:not(:Contains(" filter "))").parent().parent().slideUp(); $(list).find("dd[id='company']:Contains(" filter ")").parent().parent().slideDown(); }
else
{ $(list).find("li").slideDown(); }
return false;
}
).keyup(function () { $(this).change(); });
}
$(function () {
listFilter($("#list"));
}
);
} (jQuery));
теперь проблема в том, что когда я начинаю поиск с одного текстового поля, он работает нормально, когда я использую оба критерия поиска, тогда он начнет поиск на основе текущего нажатия клавиши текстового поля.
Я знаю, что это потому, что я написал событие изменения для текстового поля, и оно не учитывает другие значения текстового поля: (
Комментарии:
1. спасибо за помощь 🙂 Мне нужен поиск «и», т.Е. Если имя начинается с «c», а компания похожа на «h», тогда она должна показывать первый список. Я работаю над кодом, чтобы решить эту проблему 🙂
2. Тогда это просто: взяв мой ответ за отправную точку, вы должны инвертировать то, что вы делаете с условиями для slideUp и slideDown . В частности, напишите две инструкции для двух условий в slideUp, чтобы при совпадении с одним из них элемент был скрыт, и только один для slideDown, чтобы он отображался только в том случае, если выполнены оба условия. смотрите Код в моем ответе
3. спасибо @mlr за помощь, это решило мою проблему 🙂
4. Добро пожаловать: D Возможно, вы хотели бы отметить мой ответ как принятый? Спасибо
Ответ №1:
Этот код должен сделать свое дело:
РЕДАКТИРОВАТЬ: этот код фильтрует элементы в соответствии с a ИЛИ комбинацией двух условий.
(
function ($) {
jQuery.expr[':'].Contains = function (a, i, m) {
return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
};
var nameFilter, companyFilter; //store their values
function onConditionChange (nameFilter, companyFilter) {
var hideCondition = "dd" (companyFilter ? "[id='company']:not(:Contains(" companyFilter "))" : "") (nameFilter ? "[id='name']:not(:Contains(" nameFilter "))" : "");
if (nameFilter || companyFilter) {
$(list).find(hideCondition).parent().parent().slideUp();
if (nameFilter) {
$(list).find("dd[id='name']:Contains(" nameFilter ")").parent().parent().slideDown();
}
if (companyFilter) {
$(list).find("dd[id='company']:Contains(" companyFilter ")").parent().parent().slideDown();
}
} else {
$(list).find("li").slideDown();
}
return false;
}
function listFilter(list) {
$('#txtName').change(function() {
nameFilter = $(this).val();
onConditionChange(nameFilter, companyFilter);
}
).keyup(function () { $(this).change(); });
$('#txtCompany').change(function() {
companyFilter = $(this).val();
onConditionChange(nameFilter, companyFilter);
}
).keyup(function () { $(this).change(); });
}
$(function () {
listFilter($("#list"));
}
);
} (jQuery));
Я разветвил вашу скрипку, чтобы вы могли увидеть ее в действии здесь
По сути, вы отслеживаете оба условия и используете их для фильтров, если они не равны нулю (или хотя бы одно из них не равно нулю).
Я попытался применить более сухую версию с меньшим количеством дублированного кода. Тем не менее, его можно еще улучшить, но это должно решить вашу проблему.
Редактировать
После прочтения комментария, вот версия, которая фильтрует элементы, помещая два условия поиска в И .
(
function ($) {
jQuery.expr[':'].Contains = function (a, i, m) {
return (a.textContent || a.innerText || "").toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
};
var nameFilter, companyFilter; //store their values
function onConditionChange (nameFilter, companyFilter) {
var showCondition = "dd" (companyFilter ? "[id='company']:Contains(" companyFilter ")" : "") (nameFilter ? "[id='name']:Contains(" nameFilter ")" : "");
if (nameFilter || companyFilter) {
if (nameFilter) {
$(list).find("dd[id='name']:not(:Contains(" nameFilter "))").parent().parent().slideUp();
}
if (companyFilter) {
$(list).find("dd[id='company']:not(:Contains(" companyFilter "))").parent().parent().slideUp();
}
$(list).find(showCondition).parent().parent().slideDown();
} else {
$(list).find("li").slideDown();
}
return false;
}
function listFilter(list) {
$('#txtName').change(function() {
nameFilter = $(this).val();
onConditionChange(nameFilter, companyFilter);
}
).keyup(function () { $(this).change(); });
$('#txtCompany').change(function() {
companyFilter = $(this).val();
onConditionChange(nameFilter, companyFilter);
}
).keyup(function () { $(this).change(); });
}
$(function () {
listFilter($("#list"));
}
);
} (jQuery));
Ответ №2:
Вы столкнулись с проблемой, потому что вы используете один и тот же идентификатор для нескольких элементов DOM, что недопустимо. Попробуйте назначить классы вместо идентификаторов, если вы хотите вызвать одну и ту же функцию jquery для нескольких элементов DOM.
Я отмечаю проблемы в вашей разметке:
<ul>
<li>
<dl class="p_list1">
<dd id="name"> <!--OK to have an ID here---->
<b>Car</b></dd>
<dd id="company"><!--OK to have an ID here---->
Honda, Hyundai, Toyota, Suzuki</dd>
</dl>
</li>
<li>
<dl class="p_list2">
<dd id="name"><!--ID repeated, jquery function won't run for this event---->
<b>Bike</b></dd>
<dd id="company"><!--ID repeated, jquery function won't run for this event---->
Honda, Yamaha, Suzuki</dd>
</dl>
</li>
<li>
<dl class="p_list3">
<dd id="name"><!--ID repeated, jquery function won't run for this event---->
<b>Truck</b></dd>
<dd id="company"><!--ID repeated, jquery function won't run for this event---->
Tata, Volvo, Mahindra</dd>
</dl>
</li>
</ul>