1

我需要能够使用多个选择框在客户端归档一个长列表。

我已经使用一个选择框成功地做到了这一点。

<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>

还有剧本

 var names = $('#names li').clone();

$('#company').change(function() {
  var val = $(this).val();  
  $('#names').empty();
  names.filter(function(idx, el) {
    return val === 'ALL' || $(el).text().indexOf( val ) >= 0;
}).appendTo('#names');

  $('#company2').change(function() {
    var val = $(this).val();  
    $('#names').empty();
    names.filter(function(idx, el) {
    return val === 'ALL' || $(el).text().indexOf(val) >= 0;
  }).appendTo('#names');
  });
});

这几乎可行,我可以在第一个选择框中选择 GM,列表将更<li>改为

  • 雪佛兰 [GM]
  • 别克 [通用]

Buick [GM]如果我然后使用第二个选择框选择<li>将更改为仅显示

  • 别克 [通用]

这就是我想要的。但是我发现如果第二个框选择本田它将显示

  • 思域 [本田]
  • 雅阁[本田]

我的问题是如何将两者链接在一起,以便同时使用通用和本田?

没有任何过滤器的列表是:

  • 雪佛兰 [GM]
  • 别克 [通用]
  • 别克 [通用]
  • 别克 [通用]
  • 思域 [本田]
  • 雅阁[本田]
  • 焦点[福特]

当我们从第一个过滤器中选择 GM 时,它会显示

  • 雪佛兰 [GM]
  • 别克 [通用]
  • 别克 [通用]
  • 别克 [通用]

因此,如果我们从第二个过滤器中选择“别克 [GM]”,列表现在将显示

  • 别克 [通用]
  • 别克 [通用]
  • 别克 [通用]

这是正确的,但第二个过滤器设置为福特列表将显示

  • 焦点[福特]

所以过滤器不能协同工作​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ ​​​​​​​​​​​​​​​​</p>

4

2 回答 2

0

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 );
    }
});​

这是小提琴:http: //jsfiddle.net/EfEYQ/


上述解决方案有效,但我建议您不要过多地弄乱 DOM。相反,您应该在 CSS 中有一个类,然后只需在要显示hidden的 s 上切换该类: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');
    }
});​

这是小提琴:http: //jsfiddle.net/89qbV/


在评论中进一步澄清后,我认为这可能是您正在寻找的:

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');
    }
});​

这是小提琴:http: //jsfiddle.net/WfNav/

于 2012-08-24T14:35:42.630 回答
0

我使用您以前的代码处理了这个问题,但我不确定'ALL's 的行为,所以我只有第一个选择元素优先(如果第一个是全部,则显示全部)。如果你愿意,你可以添加到 filterNames() || val2 === '全部'

另外,在您的代码中,我注意到第二个选择元素上的更改事件在第一个元素更改之前不会被挂钩。于是就有了。

希望这可以帮助!

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');
}
于 2012-08-24T14:53:57.710 回答