2016-05-08 38 views
11

Sto riscontrando un problema con la mia nuova funzione di filtro delle tabelle, il problema si verifica quando si seleziona un'offerta da filtrare - piuttosto che mostrare le righe da tutti i dati filtrabili all'interno la tabella il filtro filtra solo le righe visibili meno i dati nascosti dall'impaginazione.Unisci nuova funzione filtro con impaginazione e filtro esistenti jQuery/Javascript

Per di più quando faccio clic su altro per mostrare più righe, la tabella inizia a mostrare i dati al di fuori del filtro corrente. Che non va bene

Ho anche un'altra funzione di filtro per filtrare da "Free Handsets" che è stata combinata con il mio metodo di impaginazione (codice sotto).

Come posso unire questo filtro (quello a discesa) con il mio filtro "Free Handsets" (la casella di controllo uno) e il metodo di paginazione, in modo che quando seleziono un'opzione per filtrare il filtro si occupi di tutti i dati all'interno del tabella e non solo le righe visibili visualizzate per impaginazione.

https://jsfiddle.net/51Le6o06/48/

Il violino sopra mostra entrambe le funzioni di filtraggio lavorano fianco a fianco ma non funzionano bene insieme.

Come si può vedere nel jsfiddle sopra, il filtro a discesa raccoglie le sue opzioni dall'HTML quindi le presenta nel menu a discesa, quindi tutte le opzioni sono presenti per essere filtrate da quelle appena nascoste dall'impaginazione.

Ecco jQuery e Javascript per ognuna delle funzioni.

Questo è il nuovo filtro che non funziona bene.

$(document).ready(function() { 
    $('.filter-gift').each(filterItems); 
}); 

function filterItems(e) { 
    var items = []; 
    var table = ''; 
    tableId = $(this).parent().parent().attr('tag') 

     var listItems = ""; 
     listItems += "<option value=''> -Select- </option>"; 
     $('div[tag="' + tableId + '"] table.internalActivities .information').each(function (i) { 
      var itm = $(this)[0].innerText; 
      if ($.inArray(itm, items) == -1) { 
       items.push($(this)[0].innerText); 
       listItems += "<option value='" + i + "'>" + $(this)[0].innerText + "</option>"; 
      } 
     }); 

    $('div[tag="' + tableId+ '"] .filter-gift').html(listItems); 

    $('.filter-gift').change(function() { 
    if($(this).val()!= "") { 
     var tableIdC = $(this).parent().parent().attr('tag'); 

     var text = $('div[tag="' + tableIdC + '"] select option:selected')[0].text.replace(/(\r\n|\n|\r| |)/gm, "");; 
      $('div[tag="' + tableIdC + '"] .product-information-row').each(function (i) { 
       if ($(this).text().replace(/(\r\n|\n|\r| |)/gm, "") == text) { 
        $(this).show(); 
        $(this).prev().show(); 
        $(this).next().show(); 
       } 
       else { 
        $(this).hide(); 
        $(this).prev().hide(); 
        $(this).next().hide(); 
       } 
      }); 
      } else { 
      $(this).parent().parent().find('table tr').show(); 
      } 
     });  
} 

Questa è la funzione filtro e impaginazione che desidero unire con la funzione sopra riportata (funzionante).

jQuery.fn.sortPaging = function(options) { 
    var defaults = { 
     pageRows: 2 
    }; 
    var settings = $.extend(true, defaults, options); 
    return this.each(function() { 

     var container = $(this); 
     var tableBody = container.find('.internalActivities > tbody'); 
     var dataRows = []; 
     var currentPage = 1; 
     var maxPages = 1; 
     var buttonMore = container.find('.seeMoreRecords'); 
     var buttonLess = container.find('.seeLessRecords'); 
     var buttonFree = container.find('.filter-free'); 
     var tableRows = []; 
     var maxFree = 0; 
     var filterFree = buttonFree.is(':checked'); 
     function displayRows() { 
      tableBody.empty(); 
      var displayed = 0; 
      $.each(dataRows, function(i, ele) { 
       if(!filterFree || (filterFree && ele.isFree)) { 
        tableBody.append(ele.thisRow).append(ele.nextRow); 
        displayed++; 
        if(displayed >= currentPage*settings.pageRows) { 
         return false; 
        }; 
       }; 
      }); 
     }; 
     function checkButtons() { 
      buttonLess.toggleClass('element_invisible', currentPage<=1); 
      buttonMore.toggleClass('element_invisible', filterFree ? currentPage>=maxFreePages : currentPage>=maxPages); 
     }; 
     function showMore() { 
      currentPage++; 
      displayRows(); 
      checkButtons(); 
     }; 
     function showLess() { 
      currentPage--; 
      displayRows(); 
      checkButtons(); 
     }; 
     function changedFree() { 
      filterFree = buttonFree.is(':checked'); 
      if(filterFree && currentPage>maxFreePages) { 
       currentPage=maxFreePages; 
      }; 
      displayRows(); 
      checkButtons(); 
     }; 

     tableBody.find('.product-data-row').each(function(i, j) { 
      var thisRow = $(this); 
      var nextRow = thisRow.next(); 
      var amount = parseFloat(thisRow.find('.amount').text().replace(/£/, '')); 
      var isFree = thisRow.find('.free').length; 
      maxFree += isFree; 
      dataRows.push({ 
       amount: amount, 
       thisRow: thisRow, 
       nextRow: nextRow, 
       isFree: isFree 
      }); 
     }) 

     dataRows.sort(function(a, b) { 
      return a.amount - b.amount; 
     }); 
     maxPages = Math.ceil(dataRows.length/settings.pageRows); 
     maxFreePages = Math.ceil(maxFree/settings.pageRows); 

     tableRows = tableBody.find("tr"); 

     buttonMore.on('click', showMore); 
     buttonLess.on('click', showLess); 
     buttonFree.on('change', changedFree); 

     displayRows(); 
     checkButtons(); 

    }) 

}; 

$('.sort_paging').sortPaging(); 

Obiettivi

  • far funzionare il filtro con il lavoro con impaginazione.
  • Fa funzionare il filtro contemporaneamente al filtro "Telefono libero".
+0

Penso che si incasinato ancora una volta, la sua non funziona correttamente – Rajdeep

+0

So scintilla aiutarmi – Scott

+0

Le vostre esigenze non sono chiare, si sono aggiunti alcuni nuovi rich credo – Rajdeep

risposta

2

Il tuo codice è inutilmente complicato. prova a scomporlo nei passaggi necessari. Circa il problema essenziale: fare tutto in una sola volta (Leggi qui sotto per comprendere appieno il mio approccio):

function onFilterChange() { 
    filterProducts(); 
    resetPagination(); 
    showNextPage(); 
} 

migliorare anche la vostra struttura dei dati:

se si utilizza HTML come sorgente di dati, utilizzare gli attributi nella vostra oggetti principali, che renderanno più facile trovarli. utilizzare più tag TBODY raggruppare i trs:

<tbody freeTv='false' freeHandset='false' cost='200'> 
    <tr> 
     <td>content of product 1</td> 
    </tr> 
    <tr> 
     <td>description of product 1</td> 
    </tr> 
</tbody> 
<tbody freeTv='true' freeHandset='false' cost='300'> 
    <tr> 
     <td>content of product 2</td> 
    </tr> 
    <tr> 
     <td>description of product 2</td> 
    </tr> 
</tbody> 

preferisco aggiungere classi ai miei elementi invece di rimuovere/aggiungere l'intero elemento. essere consapevoli però che questo farà un casino se si prevede di utilizzare nth-css-styling. se non hai bisogno di questo è un ottimo modo di debuggare per aggiungere interazione:

function filterProducts() { 
    $('tbody').addClass('filtered'); 
    // ... some domain-specific magic here ... 
    $('tbody[freeTv="true"]').removeClass('filtered'); 
} 

ora hai solo bisogno di un.definizione css filtrata come:

.filtered { display: none; } 

per l'impaginazione si può agire in un modo simile. prima nascondere tutto (di nuovo con css .paged { display: none; }):

function resetPagination() { 
    $('tbody').addClass('paged'); 
    $('tbody.filtered').removeClass('paged'); 
} 

poi mostrare quelli che si desidera (i primi 10 quelli di paging):

function showNextPage() { 
    $('tbody.paged').slice(0, 10).removeClass('paged'); 
} 

https://jsfiddle.net/g9zt0fan/

+0

grazie per il tuo contributo - In realtà ho convertito in datatables perché stava diventando così complicato (vedi la mia risposta sotto) l'unico problema che ho ora è lo stile di impaginazione, come la costruzione di questo per un sito web mobile. Sai come potrei cambiare lo stile di impaginazione con i datatables per mostrare più stile? https://jsfiddle.net/6k0bshb6/16/ – Scott

+0

cosa stai cercando di fare esattamente? hai uno screen design? i datatables usano una struttura DOM e attributi molto piacevoli, quindi dovrebbe essere abbastanza facile da fare con css. ad esempio: .dataTables_paginate .paginate_button.current {color: red; } dà al numero di pagina attivo un colore rosso. – ZPiDER

+0

quando faccio clic su successivo invece di andare alla pagina successiva vorrei aggiungere le righe sotto le righe attualmente visualizzate, vorrei anche che tutte le righe figlio rimangano aperte e nascondano la riga 1, vorrei anche disabilitare il clic per ordinare sulla parte superiore delle colonne mantenendo la funzionalità di ordinare le righe nel mio codice qui sotto. – Scott

1

ho risolto il problema io stesso avviando da zero e utilizzando la libreria di datatables. Ci sto ancora lavorando ma il codice è molto più semplice da gestire.

L'unico problema che sto affrontando ora è la modifica dello stile di impaginazione.

https://jsfiddle.net/6k0bshb6/16/

// This function is for displaying data from HTML "data-child-value" tag in the Child Row. 
function format(value) { 
     return '<div>Hidden Value: ' + value + '</div>'; 
    } 

// Initialization of dataTable and settings. 
    $(document).ready(function() { 
     var dataTable = $('#example').DataTable({ 
     bLengthChange: false, 
     "pageLength": 5, 
     "pagingType": "simple", 
     "order": [[ 7, "asc" ]], 
     "columnDefs": [ 
      { 
       "targets": [ 5 ], 
       "visible": false, 
       "searchable": true 
      }, 
      { 
       "targets": [ 6 ], 
       "visible": false, 
       "searchable": true 
      }, 
      { 
       "targets": [ 7 ], 
       "visible": false, 
       "searchable": true 
      } 
     ], 

// Dropdown filter function for dataTable from hidden column number 5 for filtering gifts. 
     initComplete: function() { 
      this.api().columns(5).every(function() { 
       var column = this; 
       var select = $('<select><option value="">Show all</option></select>') 
        .appendTo($("#control-panel").find("div").eq(1)) 
        .on('change', function() { 
        var val = $.fn.dataTable.util.escapeRegex(
        $(this).val()); 
        column.search(val ? '^' + val + '$' : '', true, false) 
         .draw(); 
       }); 
       column.data().unique().sort().each(function (d, j) { 
        select.append('<option value="' + d + '">' + d + '</option>') 
       }); 
      }); 
     } 
    }); 

// This function is for handling Child Rows. 
    $('#example').on('click', 'td.details-control', function() { 
      var tr = $(this).closest('tr'); 
      var row = dataTable.row(tr); 

      if (row.child.isShown()) { 
       // This row is already open - close it 
       row.child.hide(); 
       tr.removeClass('shown'); 
      } else { 
       // Open this row 
       row.child(format(tr.data('child-value'))).show(); 
       tr.addClass('shown'); 
      } 
    }); 

// Checkbox filter function below is for filtering hidden column 6 to show Free Handsets only. 
    $('#checkbox-filter').on('change', function() { 
     dataTable.draw(); 
    }); 

    $.fn.dataTable.ext.search.push(
     function(settings, data, dataIndex) { 
     var target = '£0.00'; 
     var position = data[6]; // use data for the position column 
     if($('#checkbox-filter').is(":checked")) { 
      if (target === position) { 
      return true; 
     } 
     return false; 
     } 
     return true; 
     } 
    ); 
});