jQuery使用多个选择框筛选列表
我需要能够在客户端使用多个选择框归档一个长列表 我使用一个选择框成功地完成了这项工作jQuery使用多个选择框筛选列表,jquery,list,filter,Jquery,List,Filter,我需要能够在客户端使用多个选择框归档一个长列表 我使用一个选择框成功地完成了这项工作 <select id="company"> <option selected="true" >ALL</option> <option>GM</option> <option>Honda</option> <option>Ford</option> </select> <
<select id="company">
<option selected="true" >ALL</option>
<option>GM</option>
<option>Honda</option>
<option>Ford</option>
</select>
<select id="company2">
<option selected="true" >ALL</option>
<option>Buick [GM]</option>
<option>Honda</option>
<option>Ford</option>
</select>
<ul id="names" multiple="multiple" size="8">
<li>Chevy [GM]</li>
<li>Buick [GM]</li>
<li>Civic [Honda]</li>
<li>Accord [Honda]</li>
<li>Focus [Ford]</li>
</ul>
这几乎起作用了,我可以在第一个选择框中选择GM,列表将
更改为
- 雪佛兰[通用]
- 别克[通用]
将变为仅显示
- 别克[通用]
- 思域[本田]
- 雅阁[本田]
- 雪佛兰[通用]
- 别克[通用]
- 别克[通用]
- 别克[通用]
- 思域[本田]
- 雅阁[本田]
- 福克斯[福特]
- 雪佛兰[通用]
- 别克[通用]
- 别克[通用]
- 别克[通用]
- 别克[通用]
- 别克[通用]
- 别克[通用]
- 福克斯[福特]
所以过滤器不能一起工作 您应该为两个
select
元素组合事件处理程序:
var $names = $('#names'),
$namesAll = $names.find('li'),
$company1 = $('#company'),
$company2 = $('#company2');
$company1.add( $company2 ).change(function() {
var val1 = $company1.val(),
val2 = $company2.val();
$names.empty();
if ( val1 == 'ALL' && val2 == 'ALL' ) {
$names.append( $namesAll );
}
else {
$namesAll.filter(function(i, el) {
var $el = $(el);
return ~$el.text().indexOf( val1 ) || ~$el.text().indexOf( val2 );
}).appendTo( $names );
}
});
这是小提琴:
上面的解决方案是有效的,但我建议您不要对DOM太过麻烦。相反,您应该在CSS中有一个
隐藏的
类,然后在要显示的li
上切换该类:
var $names = $('#names li'),
$company1 = $('#company'),
$company2 = $('#company2');
$company1.add( $company2 ).change(function() {
var val1 = $company1.val(),
val2 = $company2.val();
if ( val1 == 'ALL' && val2 == 'ALL' ) {
$names.removeClass('hidden');
}
else {
$names.addClass('hidden').filter(function(i, el) {
var $el = $(el);
return ~$el.text().indexOf( val1 ) || ~$el.text().indexOf( val2 );
}).removeClass('hidden');
}
});
这是小提琴:
在评论中进一步澄清后,我认为这可能是您想要的:
var $names = $('#names li'),
$company1 = $('#company'),
$company2 = $('#company2');
$company1.add( $company2 ).change(function() {
var val1 = $company1.val(),
val2 = $company2.val();
if ( val1 == 'ALL' && val2 == 'ALL' ) {
$names.removeClass('hidden');
}
else {
$names.addClass('hidden').filter(function(i, el) {
var $el = $(el),
include = true;
if ( val1 != 'ALL' && !~$el.text().indexOf( val1 ) ) include = false;
if ( val2 != 'ALL' && !~$el.text().indexOf( val2 ) ) include = false;
return include;
}).removeClass('hidden');
}
});
问题是:我是使用您以前的代码来解决这个问题的,但我不确定'ALL'的行为,所以我只有第一个select元素优先(如果first是ALL,则显示ALL)。如果需要,只需添加到filterNames()| | val2=='ALL' 另外,在您的代码中,我注意到第二个select元素上的change事件在第一个元素更改之前不会挂接。就是这样 希望这有帮助
var names = $('#names li').clone();
$('#company').change(function() {
var val = $(this).val();
var val2 = $('#company2').val();
filterNames(val, val2);
});
$('#company2').change(function() {
var val = $('#company').val();
var val2 = $(this).val();
filterNames(val, val2);
});
function filterNames(val, val2) {
$('#names').empty();
names.filter(function(idx, el) {
return val === 'ALL' || $(el).text().indexOf( val ) >= 0 || $(el).text().indexOf( val2 ) >= 0;
}).appendTo('#names');
}
我真的不明白你在追求什么。你能更详细地解释一下吗?那太好了,我真的应该把所有的代码都贴出来。然而,你的解决方案让我在选择通用汽车后仍然选择本田。@JasonBruce-这不是你想要的吗?不,我应该只能进一步过滤结果,即在选择通用汽车后,本田在选择通用汽车后,列表不应更新。仅当新列表中显示的选项为selected@JasonBruce-我不确定我是否完全理解你,但我在答案中添加了一些代码。希望对你有帮助,就这样谢谢你!对不起,没有正确地解释我自己
var names = $('#names li').clone();
$('#company').change(function() {
var val = $(this).val();
var val2 = $('#company2').val();
filterNames(val, val2);
});
$('#company2').change(function() {
var val = $('#company').val();
var val2 = $(this).val();
filterNames(val, val2);
});
function filterNames(val, val2) {
$('#names').empty();
names.filter(function(idx, el) {
return val === 'ALL' || $(el).text().indexOf( val ) >= 0 || $(el).text().indexOf( val2 ) >= 0;
}).appendTo('#names');
}