2015-06-23 4 views
5

Ho hackerato insieme una tabella di elenco delle attività di esempio di base con HTML e utilizzando jQuery. Ho allegato alcune on change eventi alla mia Filter DropDown Selection FieldsCome combinare più filtri per filtrare le righe di attività utilizzando jQuery?

Demo: http://codepen.io/jasondavis/pen/MwOwMX?editors=101

enter image description here

ho un filtro di selezione campo per ciascuno di essi:

  • Assegnato utente
  • Stato attività
  • Milestone
  • prioritarie
  • Tag

Indipendentemente tutti lavorano per ottenere il lavoro fatto nel filtrare i risultati non corrispondenti dal mio Elenco attività Tabella.

per ogni attività fila, devo conservare il valore di ciascuna opzione filtrabile in un Data Attribute come in questo esempio Task Row HTML:

 <tr id="task-3" 
      class="task-list-row" 
      data-task-id="3" 
      data-assigned-user="Donald" 
      data-status="Not Started" 
      data-milestone="Milestone 1" 
      data-priority="Low" 
      data-tags="Tag 3"> 
     <td>Task title 3</td> 
     <td>11/16/2014</td> 
     <td>02/29/2015</td> 
     <td>Low</td> 
     <td>Milestone 1</td> 
     <td>Donald</td> 
     <td>Tag 3</td> 
     </tr> 

modo che il testo vero e proprio per la riga Task non importa perché il compito la riga non mostrerà tutte le proprietà. Ciò che conta è il valore memorizzato negli attributi dei dati della riga di attività.

Una task riga/record con un Miledstone set per Milestone 2 avrà un attributo di dati come questo data-milestone="Milestone 2"

Un esempio JavaScript/jQuery codice di filtro:

// Task Milestone Dropdown Filter 
$('#milestone-filter').on('change', function() { 
    var taskMilestone = this.value; 

    if(taskMilestone === 'None'){ 
    $('.task-list-row').hide().filter(function() { 
     return $(this).data('milestone') != taskMilestone; 
    }).show(); 
    }else{ 
    $('.task-list-row').hide().filter(function() { 
     return $(this).data('milestone') == taskMilestone; 
    }).show(); 
    } 
}); 

Così come ho già detto. Posso far funzionare ognuno dei miei "FIlters" da solo, tuttavia, non appena cerco di applicare più di un filtro alla volta, non funzionerà con questo codice corrente.

Apprezzerei qualsiasi aiuto nella modifica del codice per creare un esempio di multi-filtro di lavoro per favore?

mio demo attuale è qui: http://codepen.io/jasondavis/pen/MwOwMX?editors=101


Aggiornamento Test 2

Dopo qualche pensiero, penso che forse ho bisogno di memorizzare tutti i valori di filtro corrente in variabili e poi su ogni evento change invece di questo:

return $(this).data('milestone') != taskMilestone; 

Dovrebbe invece essere più simile a questo ...

return $(this).data('milestone') != taskMilestone 
     && $(this).data('priority') != taskPriority 
     && $(this).data('tags') != taskTags 
     && .... for all filters; 

Suona bene?

Non importa, ci ho provato senza fortuna!

risposta

4

Eri vicino al tuo secondo test. Ecco una demo funzionante:

http://codepen.io/luciopaiva/pen/oXpzGw?editors=101

ho refactoring il codice un po 'e centralizzato la logica intorno updateFilters(), che è chiamato ogni volta che si verifica un evento di modifica. Inizia supponendo che ogni riga debba essere mostrata e quindi testa ogni filtro diverso dal valore predefinito (che sia 'Qualsiasi', 'Nessuno' o undefined).

A proposito, se è possibile modificare data-user-assigned in data-user, ecco un codice leggermente migliorata che riduce notevolmente il numero di linee di codice:

http://codepen.io/luciopaiva/pen/YXYGYE?editors=101

sto usando call in modo da poter passare il Elemento DOM (referenziato tramite this) al contesto di changeFilter().

Ho anche inserito tutti i filtri in un oggetto (filters) in modo che sia possibile accedere a ognuno con il suo nome, ad esempio filters[filterName] e in grado di automatizzare le cose.

Vale la pena ricordare che la variabile filters è globale e il tutto deve essere inserito in un IIFE.

Ma continuiamo. Si può andare anche oltre e rimuovere il codice boilerplate per ogni evento change, considerando che si può rinominare elemento #assigned-user-filter-#user-filter:

http://codepen.io/luciopaiva/pen/YXYGaY?editors=101

Il JavaScript di questo approccio finale:

(function() { 
    var 
    filters = { 
     user: null, 
     status: null, 
     milestone: null, 
     priority: null, 
     tags: null 
    }; 

    function updateFilters() { 
    $('.task-list-row').hide().filter(function() { 
     var 
     self = $(this), 
     result = true; // not guilty until proven guilty 

     Object.keys(filters).forEach(function (filter) { 
     if (filters[filter] && (filters[filter] != 'None') && (filters[filter] != 'Any')) { 
      result = result && filters[filter] === self.data(filter); 
     } 
     }); 

     return result; 
    }).show(); 
    } 

    function bindDropdownFilters() { 
    Object.keys(filters).forEach(function (filterName) { 
     $('#' + filterName + '-filter').on('change', function() { 
     filters[filterName] = this.value; 
     updateFilters(); 
     }); 
    }); 
    } 

    bindDropdownFilters(); 
})(); 

Qui ho usato la stessa logica del secondo approccio, utilizzando i nomi dei filtri per fare riferimento a ciascun menu a discesa. Classicplate classico!

+1

questo è semplicemente geniale! Non sono mai riuscito a trovare una soluzione così elegante e apparentemente nessun altro su SO poteva neanche! Quindi, grazie mille, sarà molto utile nella mia app di Project Management su cui sto lavorando. – JasonDavis

+0

Se ti senti come una sfida sarebbe bello aggiungere un nuovo filtro per le date di scadenza. Qualcosa in cui le opzioni sarebbero qualcosa come la data di scadenza dovuta entro 30 giorni, 7 giorni, ecc ... così come la data di scadenza scaduta da oggi. Ovviamente non sei obbligato, ma se ti piace risolvere questo tipo di problemi è un'altra cosa che volevo fare anche un filtro e penso che potrebbe non essere difficile. qualche idea? Grazie per la soluzione di cui sopra davvero apprezzare il tempo e lo sforzo è fantastico! – JasonDavis

+1

@JasonDavis Prego! A proposito del filtro della data di scadenza, dai un'occhiata a [moment.js] (http://momentjs.com/), è una libreria meravigliosa per la manipolazione di data/ora. Prova a postare ciò che hai fino a una nuova domanda e forse può iniziare da quello –