将新过滤器功能与现有分页合并并过滤jQuery / Javascript

时间:2016-05-08 22:01:33

标签: javascript jquery filter pagination

我的新表过滤功能出现问题,选择要过滤的商品时会出现问题 - 而不是显示表中所有可过滤数据的行,过滤器仅过滤可见行减去数据被分页隐藏。

最重要的是,当我点击更多以显示更多行时,表格开始显示当前过滤器之外的数据。这不好。

我还有另一个过滤功能可以通过“免费手机”进行过滤,该功能已与我的分页方法(下面的代码)结合使用。

如何将此过滤器(下拉列表)与我的“免费手机”过滤器(复选框一)和分页方法合并,这样当我选择过滤器过滤选项时会处理表格内的所有数据而不只是分页显示的可见行。

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

上面的小提示显示两个过滤功能并排工作,但它们不能很好地协同工作。

正如您在上面的jsfiddle中所看到的,下拉过滤器从HTML中收集其选项,然后在下拉菜单中显示它们,因此所有选项都可以通过分页隐藏来过滤。

以下是每个函数的jQuery和Javascript。

这是一个效果不佳的新过滤器。

$(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();
            }
        });     
}

这是我想要与上述功能(工作)合并的过滤器和分页功能。

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();

目标

  • 使用分页功能使过滤器正常工作。
  • 使用“Free Handset”过滤器同时使过滤器工作。

2 个答案:

答案 0 :(得分:2)

您的代码不必要地复杂化。试着将其分解为必要的步骤。关于你的基本问题:一气呵成(请阅读以下内容以完全理解我的方法):

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

还可以改善您的数据结构:

如果您使用html作为数据源,请使用主对象中的属性,这样可以轻松找到它们。使用多个tbody标签对您的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>

我更喜欢在我的元素中添加类而不是删除/添加整个元素。请注意,如果您计划使用nth-css-styling,这将会弄得一团糟。如果你不需要它是一个很好的,可调试的方式来添加交互:

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

现在你只需要一个.filtered css定义,如:

.filtered { display: none; }

对于分页,你可以以类似的方式行事。首先隐藏所有内容(再次使用css .paged { display: none; }):

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

然后显示你想要的那些(前10页分页):

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

https://jsfiddle.net/g9zt0fan/

答案 1 :(得分:1)

我自己从头开始并使用datatables库解决了这个问题。我还在努力,但代码处理起来要简单得多。

我现在面临的唯一问题是改变分页风格。

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