基于第一个选择动态填充第二个下拉菜单

qjp7pelc  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(308)

我使用以下代码动态填充两个下拉菜单“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>

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

yrwegjxp

yrwegjxp1#

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

// 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>

一些注意事项:
用户界面可以改进!“选择”下拉列表和“多重选择”没有任何样式/定位css。
由于从第一个(“办公室”)下拉列表到第二个(“职位”)多选列表之间存在依赖关系,因此每当我们对第一个下拉列表进行更改时,必须清除所有多选列表。如果不这样做,您可能会得到与所选下拉列表不相关的多选值。
代码可以(也可能应该)重新安排成一个更好的组织结构。目前,我的大部分代码都被转储到 initComplete 功能。
(我个人的偏好是通常避免这种类型的选择依赖,因为这可能会让用户感到惊讶。)

相关问题