首页 > 解决方案 > 如何构建一个数据表,顶部有一个保管箱过滤器,在后端计算?

问题描述

我需要更改一个 dataTable 以在其顶部(而不是在标题中)添加一个保管箱来过滤它。

我有这个列,日期像 dd/mm/yyyy,我的年份范围不是从 01/01/N 到 31/12/N。它从 01/11/N 到 31/10/N+1,此规则将用于计算可用的过滤器。

如果我只有这个到行:

 -------------------------------------------------------
|   date_header  |  header 2  |  header 3  |  header 4  |
|-------------------------------------------------------|
|   01/05/2013   |     abc    |     qwe    |     xyz    |
|-------------------------------------------------------|
|   05/11/2018   |     hdf    |     ydb    |     lot    |
 -------------------------------------------------------

我应该在 de Dropbox 上得到以下结果(尊重我谈到的规则):

<2012/2013> 和 <2018/2019>

因此,首先,我需要这个 Dropbox 来读取此列上显示的每个值并计算过滤器值。然后,使用所选范围过滤表格。

-- 编辑1 --

这是我的初始化脚本:

$element.DataTable({
    "ajax": {
        "url": this._tableDatasource,
        "dataSrc": ""
    },
    "sDom": 'ltipr',
    "bLengthChange": false,
    "paging": this._detautNombreElementsPerPage > 0,
    "pagingType": "full_numbers",
    "iDisplayLength": this._detautNombreElementsPerPage,
    "order": [[ this._defautColumnTrie, this._defautTypeTrie ]],
    "columns": this._columns,
    "columnDefs" : this._columnsProperties,
    "fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
        if ($(nRow).hasClass('even')) {
            $(nRow).addClass("alt");
        } else {
            if ($(nRow).hasClass('alt')) {
                $(nRow).removeClass("alt");
            }
        }
    },
    "fnDrawCallback": function() {
        var pageCount = Math.ceil((this.fnSettings().fnRecordsDisplay()) / this.fnSettings()._iDisplayLength);

        if (pageCount > 1)  {
            $('.dataTables_paginate').show(); 
        } else {
            $('.dataTables_paginate').hide(); 
        }
    },
    "language": {       
        "sProcessing":    "Chargement en cours...",
        "sLengthMenu":    "Montrer _MENU_ registres",
        "sZeroRecords":   "Aucun résultat n'a été trouvé",
        "sEmptyTable":    "Aucune donnée disponible pour ce tableau",
        "sInfo":          "_TOTAL_ éléments trouvés, affichage de _START_ à _END_",
        "sInfoEmpty":     "0 éléments trouvés, affichage de 0 à 0",
        "sInfoFiltered":  "(filtré au total de _MAX_ registres)",
        "sInfoPostFix":   "",
        "sSearch":        "Chercher:",
        "sUrl":           "",
        "sInfoThousands":  ",",
        "sLoadingRecords": "Chargement en cours...",
        "oPaginate": {
            "sFirst":    "Première page",
            "sLast":    "Dernière page",
            "sNext":    "Page suivante",
            "sPrevious": "Page précédente"
        }
    },
    "initComplete": function() {
        if ($(this).attr('id') == "tableIndisponibilitesPassees") {
            var dates = $('#tableIndisponibilitesPassees tr td:first-child').toArray();

            populate_dropdown(dates);

            //$('#tableIndisponibilitesPassees').dataTable().fnClearTable();

       //$('#tableIndisponibilitesPassees').dataTable().fnFilter("20/10/2015 08:00:00").draw();

            set_handler();
        }
    }
});

我必须添加 initComplete 来填充表格。

这是我的填充下拉列表:

function populate_dropdown(dates) {
    // make an empty array variable to hold the list of saisons
    var saisons = [];

    // loop through the dates
    for (var i = 0; i < dates.length; i++) {

        var year = Number($(dates[i]).html().split(' ')[0].split('/')[2]);
        var month = Number($(dates[i]).html().split(' ')[0].split('/')[1] - 1);
        var day = Number($(dates[i]).html().split(' ')[0].split('/')[0]);
        var datePFHA = new Date(year, month, day);

        var dateDebutSaison = new Date(year, 10, 1);

        // now let's calculate the season
        var saison;
        if (datePFHA < dateDebutSaison) {
            saison = Number(year-1) + "/" + year;
        } else {
            saison = year + "/" + Number(year+1);
        }

        // now let's add that saison to the seasons array (if it's not already in the array!)
        if ($.inArray(saison, saisons) == -1) {
            saisons.push(saison);
        }
    }

    // now that we're done looping through and building the seasons list, let's sort the array
    saisons.sort();

    // make a variable to hold all the <option> fields for the select dropdown
    var options = "";

    // loop through the years and make the options fields
    $.each(saisons, function(key,value) {
        options += "<option> Saison " + value + "</option>";
    }); 

    // take the new options string that we've built and put it inside the <select> dropdown
    $('#filtre_saison').append(options);
}

现在我正在尝试像这样设置处理程序:

function set_handler(dataTable) {
    console.log("set_handler");
    var filtre = $('#filtre_saison').on('change', function() {
        // when someone changes the filter, get the beginning and ending of the season
        var yearsSaison = $("#filtre_saison").val().split(' ')[1];
        var debutSaison = new Date(yearsSaison.split('/')[0],10,01);
        var finSaison = new Date(debutSaison.getFullYear() + 1, debutSaison.getMonth(), debutSaison.getDate());

        console.log($('#tableIndisponibilitesPassees'));
        console.log($('#tableIndisponibilitesPassees').dataTable());
     console.log($('#tableIndisponibilitesPassees').dataTable().fnFilter("20/10/2015 08:00:00"));
     console.log($('#tableIndisponibilitesPassees').dataTable().fnFilter("20/10/2015 08:00:00").draw());
        $('#tableIndisponibilitesPassees').dataTable().fnFilter("20/10/2015 08:00:00").draw();
        //$(dataTable).search("20/10/2015 08:00:00").draw();

        //filter_table(debutSaison, finSaison);
    });
}

我已经在 dataTable 上尝试了搜索方法,但它不起作用。返回一个错误,说明搜索不是一个函数。我已经尝试过使用 fnFilter 但现在它在绘图函数中返回一个错误说:

无法读取未定义的属性“绘制”

我已经检查并在 fnFilter 函数之后返回未定义。

--- 编辑 2 ---

差点忘了。这是我的 html 代码:

<select name="filtre_saison" id="filtre_saison">
</select>

感谢你的帮助

标签: javascriptjavajqueryspringdatatables

解决方案


好的,没有任何关于如何构建表格等的细节,解决这个问题的一般方法可能是使用 javascript/jQuery 循环遍历date字段并构建年份列表。然后从该年份列表中,您可以填充一个下拉列表。然后,您将更改处理程序添加到下拉列表并使用 javascript 根据所选年份显示/隐藏元素。

这是一个快速而肮脏的示例,它假设了几件事:

  1. 保存日期的字段有一个类(在我的例子中,'date_element')
  2. 字段中的日期格式一致

您可以运行下面的工作片段来查看它的实际效果。我添加了很多代码注释来解释某些行在做什么。

希望能帮助到你!(我希望我不只是为你做作业......)。

// trigger the function that populates the dropdown when the page has finished loading, and then add a change handler on the dropdown
$(document).ready(function() {
  populate_dropdown();
  set_handler();
});

function populate_dropdown() {
  // make an empty array variable to hold the list of years
  var years = [];
  
  // loop through the date_header fields (assuming that the elements have a class of date_element)
  $('.date_element').each(function(){
    // $(this) inside the each function refers to the <td class='date_element'> element
    var this_date = $(this).html();
    // get the year from the date. It would be better to use actual Date functions, but if the 
    // dates are consistent, we can just break them apart on the / characters and grab the last value
    var this_year = Number(this_date.split('/')[2]);
    // now let's add that year to the years array (if it's not already in the array!)
    if ($.inArray(this_year, years) == -1) {
      years.push(this_year)
    }
  });
  
  // now that we're done looping through and building the year list, let's sort the array
  years.sort();
  
  // make a variable to hold all the <option> fields for the select dropdown
  var options = "";
  
  // loop through the years and make the options fields
  $.each(years, function(key,value) {
    options += "<option>" + value + "/" + Number(value+1) + "</option>";
  }); 
  
  // take the new options string that we've built and put it inside the <select> dropdown
  $('#year_filter').append(options)
}


function set_handler() {
  $('#year_filter').change(function() {
    // when someone changes the filter, get the value of the first year
    var selected_year = $("#year_filter").val().split('/')[0];
    // make sure it's a number 
    if (!isNaN(selected_year)) {
      filter_table(selected_year);
    } else {
      show_all_rows();
    }
  });
}

function filter_table(selected_year) {
  //loop through the table rows, show ones that have the year and hide ones that don't have it
  $('.date_element').each(function() {
    if ($(this).html().indexOf(selected_year) == -1) {
      //this row doesn't contain that year, let's hide the whole <tr>
      $(this).parent().hide();
    } else {
      $(this).parent().show()
    }
  });
}

function show_all_rows() {
  $('.date_element').each(function() {
    $(this).parent().show();
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<form>
  <select id="year_filter" name="year_filter"><option>Filter By Year</option></select>
</form>

<table>
  <tr>
    <th>date_header</th>
    <th>header 1</th>
    <th>header 2</th>
    <th>header 3</th>
  </tr>
  <tr>
    <td class='date_element'>01/05/2013</td>
    <td>abc</td>
    <td>qwe</td>
    <td>xyz</td>
  </tr>
  <tr>
    <td class='date_element'>05/11/2018</td>
    <td>hdf</td>
    <td>ydb</td>
    <td>lot</td>
  </tr>  
</table>


推荐阅读