【问题标题】:Dynamically populate second drop down menu based on first selection根据第一个选择动态填充第二个下拉菜单
【发布时间】:2021-09-30 21:28:37
【问题描述】:

我正在使用以下代码动态填充两个下拉菜单“searchProject”和“searchHR”。用户可以从“searchProject”中选择一个值,从“searchHR”中选择多个值来过滤数据表。

我正在尝试让第二个下拉菜单“searchHR”填充基于在第一个下拉菜单“searchProject”中选择的单个值的值。

这是我当前的代码:

  var sortFunction = function (a, b) {
        if (a < b) return -1;
        if (a > b) return 1;
        return 0;
    };
       

 $(document).ready(function () {
        var ex_table = $('#data_table').DataTable({
            "order": [],
            pageLength: 50,
            ajax: {
                url: '/db',
                dataSrc: "",
                type: "POST",
                'data': function (d) {
                    return $.extend({}, d, {
                        "project_name": $('#searchProject').val(),
                        "hour": $('#searchHR').val(),
                    });
                },
                "serverSide": true,
            },
    
            columns: [
                {data: 'project_name'},
                {data: 'id'},
                {data: 'hour'},  
            ],
            "initComplete": function () {
                ex_table.columns([0]).every(function () {
                    const column = this;
                    const select = $('#searchProject')
                        .on('change', function () {
                            const Project_val = $(this).val();
                            column.search(Project_val).draw();
                        });
                    column.data().unique().sort().each(function (d) {
                        select.append('<option value="' + d + '">' + d + '</option>')
                    });
                });
    
    
                ex_table.columns([2]).every(function () {
                    const column = this;
                    const select = $('#searchHR')
                        .on('change', function () {
                            var vals = $('option:selected', this).map(function (index, element) {
                                return $.fn.dataTable.util.escapeRegex($(element).val());
                            }).toArray().join('|');
    
                            column.search(vals.length > 0 ? '^(' + vals + ')$' : '', true, false).draw();
                        });
    
                    column.data().unique().sort(sortFunction).each(function (d) {
                        select.append('<option value="' + d + '">' + d + '</option>')
                    });
                });
            }
        });
})

HTML:

    <label for="searchProject"></label><select id="searchProject" class="js-example-basic-single" style="width: 10%">
    <option></option>
</select>
    <label for="searchHR"></label><select id="searchHR" class="js-example-basic-multiple" multiple="multiple" style="width:15%">
    <option></option>
</select>

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: jquery datatables


    【解决方案1】:

    这是一种方法 - 我对代码进行了注释以提供对主要步骤的解释。大部分复杂性来自 (a) 管理两个选择小部件之间的关系,以及 (b) 处理来自多选的值数组。

    // inline test data:
    var dataSet = [
        {
          "id": "123",
          "name": "Tiger Nixon",
          "position": "System Architect",
          "salary": "$320,800",
          "start_date": "2011/04/25",
          "office": "Edinburgh",
          "extn": "5421"
        },
        {
          "id": "456",
          "name": "Donna Snider",
          "position": "Customer Support",
          "salary": "$112,000",
          "start_date": "2011/01/25",
          "office": "New York",
          "extn": "4226"
        },
        {
          "id": "567",
          "name": "Cedric Kelly",
          "position": "Senior Javascript Developer",
          "salary": "$433,060",
          "start_date": "2012/03/29",
          "office": "Edinburgh",
          "extn": "6224"
        },
        {
          "id": "432",
          "name": "Airi Satou",
          "position": "Accountant",
          "salary": "$162,700",
          "start_date": "2008/11/28",
          "office": "Tokyo",
          "extn": "5407"
        },
        {
          "id": "987",
          "name": "Brielle Williamson",
          "position": "Integration Specialist",
          "salary": "$372,000",
          "start_date": "2012/12/02",
          "office": "New York",
          "extn": "4804"
        }
      ];
    
    $(document).ready(function() {
    
    var table = $('#example').DataTable( {
      data: dataSet,
      orderCellsTop: true,
      columns: [
        { data: "name" },
        { data: "office" },
        { data: "position" },
        { data: "extn" }
      ],
      initComplete: function () {
        this.api().columns( [1, 2] ).every( function () {
          var column = this;
          var colIdx = column.index();
          var node;
          var select;
          if (colIdx === 1) {
            node = $('#office_select');
            select = $('<select><option value=""></option></select>');
          } else {
            node = $('#position_select');
            select = $('<select multiple><option value=""></option></select>');
          }
    
          select.appendTo( $(node).empty() )
            .on( 'change', function () {
              // the contents of the multi-select, as an array of values:
              var val = $(this).val();
              if (colIdx === 1) { // this is the standard select column (for "office")
                val = $.fn.dataTable.util.escapeRegex(val);
                column.search( val ? '^' + val + '$' : '', true, false ).draw();
                rebuildPositionSelect();
              } else { // this is the multi-select column (for "position"):
                // build a string containing the pipe-separated multiselect values, but
                // with each value escaped for any regex characters it may contain:
                var vals = val.map(x => $.fn.dataTable.util.escapeRegex(x)).join('|');           
                column.search( vals ? '^' + vals + '$' : '', true, false ).draw();
              }
            } );
    
          column.data().unique().sort().each( function ( val ) {
            select.append( '<option value="' + val +'">' + val + '</option>' )
          } );
    
        } );
      }
    } ); 
    
    function rebuildPositionSelect() {
      var select = $('#position_select select').empty().append('<option value=""></option>');
      // note the use of {search:'applied'} here, to only capture visible "position" values:
      var column = table.column(2, {search:'applied'});
      // we need to reset the "position" search back to "none", to unfilter that column,
      // otherwise our new filter may not find the already filtered data:
      column.search('').draw();
      column.data().unique().sort().each( function ( val ) {
        select.append( '<option value="' + val +'">' + val + '</option>' );
      } );
    }
    
    } );
    <!doctype html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>Demo</title>
      <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
      <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
      <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
      <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
    
    </head>
    
    <body>
    
    <div style="margin: 20px;">
    
        <div>
            <span>Office: </span>
            <span id="office_select"></span>
            <span> Position: </span>
            <span id="position_select"></span>
        </div>
    
        <br><br>
    
        <table id="example" class="display dataTable cell-border" style="width:100%">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Office</th>
                    <th>Position</th>
                    <th>Extn.</th>
                </tr>
            </thead>
        </table>
    
    </div>
    
    </body>
    </html>

    一些注意事项:

    1. 用户界面可以改进!选择下拉菜单和多选没有任何样式/定位 CSS。

    2. 因为从第一个(“办公室”)下拉列表到第二个(“职位”)多选存在依赖关系,所以每当我们对第一个下拉菜单进行更改时,我们都必须清除所有多选选择-下。如果没有这个,您最终可能会得到与所选下拉列表无关的多选值。

    3. 代码可以(并且可能应该)重新排列成组织更好的结构。目前,我的大部分代码都只是转储到initComplete 函数中。

    (我纯粹的个人偏好是通常避免这种类型的选择依赖,因为它可能会让用户感到惊讶。)

    【讨论】:

      猜你喜欢
      • 2021-12-11
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      • 2016-12-20
      相关资源
      最近更新 更多