2012-01-09 20 views
6

Desidero filtrare alcuni contenuti utilizzando le caselle di controllo.Filtro con caselle di controllo usando jQuery

Sono riuscito a farlo grazie a un earlier post che ho semplificato un po 'qui DEMO.

Il mio problema è che ogni oggetto di contenuto può avere più di una categoria allegata. Quando seleziono la categoria A e la categoria B e quindi deseleziono la categoria B, l'elemento di contenuto che ha entrambe le categorie allegate viene rimosso.

Il progetto su cui sto lavorando conterrà più di due categorie. Un elemento di contenuto può avere molte categorie attaccati

HTML:

<ul id="filters"> 
    <li> 
     <input type="checkbox" value="categorya" id="filter-categorya" /> 
     <label for="filter-categorya">Category A</label> 
    </li> 
    <li> 
     <input type="checkbox" value="categoryb" id="filter-categoryb" /> 
     <label for="filter-categoryb">Category B</label> 
    </li> 
</ul> 

<div class="categorya categoryb">A, B</div> 
<div class="categorya">A</div> 
<div class="categorya">A</div> 
<div class="categorya">A</div> 
<div class="categoryb">B</div> 
<div class="categoryb">B</div> 
<div class="categoryb">B</div> 

Javascript:

$('input').click(function() { 
    var category = $(this).val(); 

    if (!$(this).attr('checked')) $('.' + category).hide(); 
    else $('.' + category).show(); 

}); 

risposta

12

Credo che i due approcci più semplici sarebbero al clic di una delle caselle di controllo del filtro sia:

  1. Nascondi tutti<div> elementi, quindi scorrere le caselle di controllo e per ogni controllati uno .show() il <div> elementi con la categoria associata.

  2. ciclo attraverso tutte le caselle di fare una lista delle classi da visualizzare, quindi scorrere gli elementi <div>, controllando ciascuno di vedere se ha una di queste classi e .hide() o .show() come appropriato.

C'è qualche selettore generale è possibile utilizzare per ottenere tutti i <div> elementi? Hanno un particolare elemento contenitore, come il modo in cui tutte le caselle di controllo sono discendenti di "#filters"?

// Solution 1 

$("#filters :checkbox").click(function() { 
    $("div").hide(); 
    $("#filters :checkbox:checked").each(function() { 
     $("." + $(this).val()).show(); 
    }); 
}); 

Demo: http://jsfiddle.net/6wYzw/41/

// Solution 2 

$("#filters :checkbox").click(function() { 

    var re = new RegExp($("#filters :checkbox:checked").map(function() { 
          return this.value; 
         }).get().join("|")); 
    $("div").each(function() { 
     var $this = $(this); 
     $this[re.source!="" && re.test($this.attr("class")) ? "show" : "hide"](); 
    }); 
}); 

Demo: http://jsfiddle.net/6wYzw/42/

Credo che il primo modo è più breve e più facile da mantenere ...

+0

Entrambe le soluzioni sono subito disponibili! –

+0

ottimo lavoro +1 !!! – Logz

0

http://jsfiddle.net/FfZsC/

$('input').click(function() { 
    var category = $(this).val(); 

    $('.' + category).each(function() { 
     var anyChecked = false; 
     var classArray = this.className.split(/\s+/); 

     for(idx in classArray) 
     { 
      if ($('#filter-' + classArray[idx]).is(":checked")) 
      { 
       anyChecked = true; 
       break; 
      } 
     } 

     if (! anyChecked) $(this).hide(); 
     else $(this).show(); 

    }); 

}); 

Fondamentalmente, io controllare ogni categoria casella di controllo associata con gli elementi relativo al filtro attualmente selezionato . Se qualcuno di questi viene ancora controllato, viene visualizzato l'elemento; altrimenti, è nascosto.

+0

Questa soluzione funziona anche fuori dalla scatola! –

1

Quando si fa clic su una casella di controllo accumulo un selettore come questo:

var selector = $('input:checkbox').map(function(){ 
    return this.checked ? '.' + this.id : ''; 
}).get().join(''); 

Questo genererà un selettore come categoryb.categoryc (un selettore css AND). È quindi possibile nascondere tutti e mostrare quelli che soddisfano il selettore.

$('div[class^="category"]') 
    .hide() 
    .filter(selector) 
    .show(); 

Provalo sul jsbin

Codice lavoro:

$('input').click(function() { 
    var selector = $('input:checkbox').map(function(){ 
     return this.checked ? '.' + this.id : ''; 
    }).get().join(''); 
    console.log(selector); 

    var all = $('div[class^="category"]'); 
    if(selector.length) 
     all.hide().filter(selector).show() 
    else all.show(); 
}); 
3

ho voluto aggiungere animazioni jQuery per mostrare e nascondere. Le soluzioni di cui sopra non consentivano questo (nascondendo prima tutto, quindi mostrando) o erano ingombranti con espressioni regolari. La mia soluzione, sulla base di quanto sopra, è la seguente:

var showselector = $('input:checkbox').map(function(){ 
     return this.checked ? '.' + this.id : null; 
    }).get().join(','); 
var hideselector = (showselector) ? ':not(' + showselector + ')' : '*'; 

$("div").filter(showselector).slideDown(1500); 
$("div").filter(hideselector).slideUp(1500); 
0

@Josiah Ruddell - il codice non è in esecuzione in IE9

ho aggiunto "window.console & &" al ... console .log ... per eseguire correelymente in IE9

$('input').click(function() { 
    var selector = $('input:checkbox').map(function(){ 
     return this.checked ? '.' + this.id : ''; 
    }).get().join(''); 
    window.console && console.log(selector); 

    var all = $('div[class^="category"]'); 
    if(selector.length) 
     all.hide().filter(selector).show() 
    else all.show(); 
}); 
Problemi correlati