根据第一个选择动态填充第二个下拉菜单
Posted
技术标签:
【中文标题】根据第一个选择动态填充第二个下拉菜单【英文标题】: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>
任何帮助将不胜感激。谢谢。
【问题讨论】:
【参考方案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>
一些注意事项:
用户界面可以改进!选择下拉菜单和多选没有任何样式/定位 CSS。
因为从第一个(“办公室”)下拉列表到第二个(“职位”)多选存在依赖关系,所以每当我们对第一个下拉菜单进行更改时,我们都必须清除所有多选选择-下。如果没有这个,您最终可能会得到与所选下拉列表无关的多选值。
代码可以(并且可能应该)重新排列成组织更好的结构。目前,我的大部分代码都只是转储到initComplete
函数中。
(我纯粹的个人偏好是通常避免这种类型的选择依赖,因为它可能会让用户感到惊讶。)
【讨论】:
以上是关于根据第一个选择动态填充第二个下拉菜单的主要内容,如果未能解决你的问题,请参考以下文章