Select2 多选选项以在另一个多选中显示选项
Select2 multiselect options to display options in another multiselect
我刚刚将我的一个 multiselect 切换为 select2
,因为我之前的复选框 multiselect 与我的新页面模板 CSS 不兼容并且看起来非常不合适。
第一个 multiselect(现在是 select2
),用户可以 select 他们的大量选项和下面的第二个 multiselect将填充与第一个已经 selected 相关的选项,并且该字段是只读的。这以前工作得很好,但现在不再这样做了。
这是我正在使用的代码。 select2
中 hazards
的选项是从按预期工作的数据库中提取的。
$(document).ready(function() {
$('#hazards').select2();
});
window.addEventListener('DOMContentLoaded', () => {
let hprops = document.querySelector('#hp_codes')
document.querySelector('#hazards').addEventListener('change', e => {
let options = e.target.options;
let hazards = [];
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
hazards.push(options[i].value);
}
}
hprops.innerHTML = '';
hprops.setAttribute('disabled', true); // disable until we get the data in there
// ajax to get actual data ...
let results = []
if (hazards.includes("H200") || hazards.includes("H201")) results.push('HP1')
if (hazards.includes('H300') || hazards.includes("H301")) results.push('HP6')
if (hazards.includes('H400') || hazards.includes("H410")) results.push('HP14')
results.forEach(r => hprops.innerHTML += `<option selected value='${r}'>${r}</option?`)
hprops.removeAttribute('disabled');
})
})
// array_unique compressed:
function array_unique(d){var c="",b={},e="";var a=function(h,g){var f="";for(f in g){if(g.hasOwnProperty(f)){if((g[f]+"")===(h+"")){return f}}}return false};for(c in d){if(d.hasOwnProperty(c)){e=d[c];if(false===a(e,b)){b[c]=e}}}return b}
var optionValues = [];
$('#hp_codes').each(function() {
optionValues.push($(this).val());
$(this).remove(); // remove the option element
});
var cleanedArray = array_unique(optionValues); // clean the array
// let's go to paint the new options
for(var i in cleanedArray) {
var opt = $('<option/>')
.attr('value', cleanedArray[i]) // note that the value is equal than the text
.text(cleanedArray[i]);
$('#hp_codes').append(opt);
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">Hazard Statements: </label>
<span class="text-danger">*</span> </div>
<div class="mb-3 col-sm-8">
<select class="form-control select2" data-toggle="select2" id="hazards" name="hazards" multiple required>
<option value="H200">H200</option>
<option value="H201">H201</option>
<option value="H300">H300</option>
<option value="H301">H301</option>
<option value="H400">H400</option>
<option value="H410">H410</option>
</select>
</div>
</div>
</br>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">HP Codes: </label>
</div>
<div class="col-sm-8">
<select class="form-control" name="hp_codes" id="hp_codes" multiple readonly>
</select>
</div>
</div>
当我在浏览器中调试它时,它当前显示
$
这一行 $('#hp_codes').each(function() {
未定义。我不确定如何解决这个问题,因为它之前工作正常。
编辑:如果没有 JQuery,它应该是这样工作的
window.addEventListener('DOMContentLoaded', () => {
let hprops = document.querySelector('#hp_codes')
document.querySelector('#hazards').addEventListener('change', e => {
let options = e.target.options;
let hazards = [];
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
hazards.push(options[i].value);
}
}
hprops.innerHTML = '';
hprops.setAttribute('disabled', true); // disable until we get the data in there
// ajax to get actual data ...
let results = []
if (hazards.includes("H200") || hazards.includes("H201")) results.push('HP1')
if (hazards.includes('H300') || hazards.includes("H301")) results.push('HP6')
if (hazards.includes('H400') || hazards.includes("H410")) results.push('HP14')
results.forEach(r => hprops.innerHTML += `<option selected value='${r}'>${r}</option?`)
hprops.removeAttribute('disabled');
})
})
// array_unique compressed:
function array_unique(d){var c="",b={},e="";var a=function(h,g){var f="";for(f in g){if(g.hasOwnProperty(f)){if((g[f]+"")===(h+"")){return f}}}return false};for(c in d){if(d.hasOwnProperty(c)){e=d[c];if(false===a(e,b)){b[c]=e}}}return b}
var optionValues = [];
$('#hp_codes').each(function() {
optionValues.push($(this).val());
$(this).remove(); // remove the option element
});
var cleanedArray = array_unique(optionValues); // clean the array
// let's go to paint the new options
for(var i in cleanedArray) {
var opt = $('<option/>')
.attr('value', cleanedArray[i]) // note that the value is equal than the text
.text(cleanedArray[i]);
$('#hp_codes').append(opt);
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">Hazard Statements: </label>
<span class="text-danger">*</span> </div>
<div class="mb-3 col-sm-8">
<select class="form-control" id="hazards" name="hazards" multiple required>
<option value="H200">H200</option>
<option value="H201">H201</option>
<option value="H300">H300</option>
<option value="H301">H301</option>
<option value="H400">H400</option>
<option value="H410">H410</option>
</select>
</div>
</div>
</br>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">HP Codes: </label>
</div>
<div class="col-sm-8">
<select class="form-control" name="hp_codes" id="hp_codes" multiple readonly>
</select>
</div>
</div>
简化了您的代码并放置了触发更改的核心逻辑。这将自动对危险选项中的任何选择或删除做出反应。
<html>
<head>
<title>Expense Tracker</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
$(document).ready(function() {
$('#hazards').select2();
$('#hazards').on('change', function(){
console.log($(this).val());
$('#hp_codes').html('');
$($(this).val()).each(function(i, node){
//node is the value selected from Hazards
//do the db call here.. I have just used 1 value, but this can be array of values resulted from DB
var opt = $('<option/>')
.attr('value', node+' - DB options') // note that the value is equal than the text
.text(node+' - DB options');
$('#hp_codes').append(opt);
});
});
});
</script>
</head>
<body>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">Hazard Statements: </label>
<span class="text-danger">*</span> </div>
<div class="mb-3 col-sm-8">
<select class="form-control select2" data-toggle="select2" id="hazards" name="hazards" multiple required>
<option value="H200">H200</option>
<option value="H201">H201</option>
<option value="H300">H300</option>
<option value="H301">H301</option>
<option value="H400">H400</option>
<option value="H410">H410</option>
</select>
</div>
</div>
</br>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">HP Codes: </label>
</div>
<div class="col-sm-8">
<select class="form-control" name="hp_codes" id="hp_codes" multiple readonly>
</select>
</div>
</div>
</body>
</html>
更接近您的原始代码,我相信这是需要的?
由于某些原因 #hazards
,addEventListener
没有触发,所以我改用 $('#hazards').on('change', ...
。
另外,似乎DOMContentLoaded
处理程序之后的所有代码都没有使用?
不管怎样,我添加了一个替代的唯一函数来过滤数组,commented-out,如果你觉得它有用的话。
// $(document).ready(function() {
// $('#hazards').select2();
// });
window.addEventListener('DOMContentLoaded', () => {
$('#hazards').select2();
let hprops = document.getElementById('hp_codes')
// document.querySelector('#hazards').addEventListener('change', e => {
// The hazards addEventListener was not firing?
$('#hazards').on('change', e => {
let options = e.target.options;
let hazards = [];
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
hazards.push(options[i].value);
}
}
hprops.innerHTML = '';
hprops.setAttribute('disabled', true); // disable until we get the data in there
// ajax to get actual data ...
let results = []
if (hazards.includes("H200") || hazards.includes("H201")) results.push('HP1')
if (hazards.includes('H300') || hazards.includes("H301")) results.push('HP6')
if (hazards.includes('H400') || hazards.includes("H410")) results.push('HP14')
results.forEach(r => hprops.innerHTML += `<option selected value="${r}">${r}</option>`)
hprops.removeAttribute('disabled');
})
})
// array_unique compressed:
function array_unique(d){var c="",b={},e="";var a=function(h,g){var f="";for(f in g){if(g.hasOwnProperty(f)){if((g[f]+"")===(h+"")){return f}}}return false};for(c in d){if(d.hasOwnProperty(c)){e=d[c];if(false===a(e,b)){b[c]=e}}}return b}
/* // an alternative unique
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
*/
var optionValues = [];
// $('#hp_codes').each(function() { // this removed the select!
$('#hp_codes').children().each(function() {
optionValues.push($(this).val());
$(this).remove(); // remove the option element
});
var cleanedArray = array_unique(optionValues); // clean the array
// var cleanedArray = optionValues.filter(onlyUnique); // clean the array
// let's go to paint the new options
for(var i in cleanedArray) {
var opt = $('<option/>')
.prop('value', cleanedArray[i]) // note that the value is equal than the text
.text(cleanedArray[i]);
$('#hp_codes').append(opt);
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">Hazard Statements: </label>
<span class="text-danger">*</span> </div>
<div class="mb-3 col-sm-8">
<select class="form-control select2" data-toggle="select2" id="hazards" name="hazards" multiple required>
<option value="H200">H200</option>
<option value="H201">H201</option>
<option value="H300">H300</option>
<option value="H301">H301</option>
<option value="H400">H400</option>
<option value="H410">H410</option>
</select>
</div>
</div>
</br>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">HP Codes: </label>
</div>
<div class="col-sm-8">
<select class="form-control" name="hp_codes" id="hp_codes" multiple readonly>
</select>
</div>
</div>
我刚刚将我的一个 multiselect 切换为 select2
,因为我之前的复选框 multiselect 与我的新页面模板 CSS 不兼容并且看起来非常不合适。
第一个 multiselect(现在是 select2
),用户可以 select 他们的大量选项和下面的第二个 multiselect将填充与第一个已经 selected 相关的选项,并且该字段是只读的。这以前工作得很好,但现在不再这样做了。
这是我正在使用的代码。 select2
中 hazards
的选项是从按预期工作的数据库中提取的。
$(document).ready(function() {
$('#hazards').select2();
});
window.addEventListener('DOMContentLoaded', () => {
let hprops = document.querySelector('#hp_codes')
document.querySelector('#hazards').addEventListener('change', e => {
let options = e.target.options;
let hazards = [];
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
hazards.push(options[i].value);
}
}
hprops.innerHTML = '';
hprops.setAttribute('disabled', true); // disable until we get the data in there
// ajax to get actual data ...
let results = []
if (hazards.includes("H200") || hazards.includes("H201")) results.push('HP1')
if (hazards.includes('H300') || hazards.includes("H301")) results.push('HP6')
if (hazards.includes('H400') || hazards.includes("H410")) results.push('HP14')
results.forEach(r => hprops.innerHTML += `<option selected value='${r}'>${r}</option?`)
hprops.removeAttribute('disabled');
})
})
// array_unique compressed:
function array_unique(d){var c="",b={},e="";var a=function(h,g){var f="";for(f in g){if(g.hasOwnProperty(f)){if((g[f]+"")===(h+"")){return f}}}return false};for(c in d){if(d.hasOwnProperty(c)){e=d[c];if(false===a(e,b)){b[c]=e}}}return b}
var optionValues = [];
$('#hp_codes').each(function() {
optionValues.push($(this).val());
$(this).remove(); // remove the option element
});
var cleanedArray = array_unique(optionValues); // clean the array
// let's go to paint the new options
for(var i in cleanedArray) {
var opt = $('<option/>')
.attr('value', cleanedArray[i]) // note that the value is equal than the text
.text(cleanedArray[i]);
$('#hp_codes').append(opt);
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">Hazard Statements: </label>
<span class="text-danger">*</span> </div>
<div class="mb-3 col-sm-8">
<select class="form-control select2" data-toggle="select2" id="hazards" name="hazards" multiple required>
<option value="H200">H200</option>
<option value="H201">H201</option>
<option value="H300">H300</option>
<option value="H301">H301</option>
<option value="H400">H400</option>
<option value="H410">H410</option>
</select>
</div>
</div>
</br>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">HP Codes: </label>
</div>
<div class="col-sm-8">
<select class="form-control" name="hp_codes" id="hp_codes" multiple readonly>
</select>
</div>
</div>
当我在浏览器中调试它时,它当前显示
$
这一行 $('#hp_codes').each(function() {
未定义。我不确定如何解决这个问题,因为它之前工作正常。
编辑:如果没有 JQuery,它应该是这样工作的
window.addEventListener('DOMContentLoaded', () => {
let hprops = document.querySelector('#hp_codes')
document.querySelector('#hazards').addEventListener('change', e => {
let options = e.target.options;
let hazards = [];
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
hazards.push(options[i].value);
}
}
hprops.innerHTML = '';
hprops.setAttribute('disabled', true); // disable until we get the data in there
// ajax to get actual data ...
let results = []
if (hazards.includes("H200") || hazards.includes("H201")) results.push('HP1')
if (hazards.includes('H300') || hazards.includes("H301")) results.push('HP6')
if (hazards.includes('H400') || hazards.includes("H410")) results.push('HP14')
results.forEach(r => hprops.innerHTML += `<option selected value='${r}'>${r}</option?`)
hprops.removeAttribute('disabled');
})
})
// array_unique compressed:
function array_unique(d){var c="",b={},e="";var a=function(h,g){var f="";for(f in g){if(g.hasOwnProperty(f)){if((g[f]+"")===(h+"")){return f}}}return false};for(c in d){if(d.hasOwnProperty(c)){e=d[c];if(false===a(e,b)){b[c]=e}}}return b}
var optionValues = [];
$('#hp_codes').each(function() {
optionValues.push($(this).val());
$(this).remove(); // remove the option element
});
var cleanedArray = array_unique(optionValues); // clean the array
// let's go to paint the new options
for(var i in cleanedArray) {
var opt = $('<option/>')
.attr('value', cleanedArray[i]) // note that the value is equal than the text
.text(cleanedArray[i]);
$('#hp_codes').append(opt);
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">Hazard Statements: </label>
<span class="text-danger">*</span> </div>
<div class="mb-3 col-sm-8">
<select class="form-control" id="hazards" name="hazards" multiple required>
<option value="H200">H200</option>
<option value="H201">H201</option>
<option value="H300">H300</option>
<option value="H301">H301</option>
<option value="H400">H400</option>
<option value="H410">H410</option>
</select>
</div>
</div>
</br>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">HP Codes: </label>
</div>
<div class="col-sm-8">
<select class="form-control" name="hp_codes" id="hp_codes" multiple readonly>
</select>
</div>
</div>
简化了您的代码并放置了触发更改的核心逻辑。这将自动对危险选项中的任何选择或删除做出反应。
<html>
<head>
<title>Expense Tracker</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script>
$(document).ready(function() {
$('#hazards').select2();
$('#hazards').on('change', function(){
console.log($(this).val());
$('#hp_codes').html('');
$($(this).val()).each(function(i, node){
//node is the value selected from Hazards
//do the db call here.. I have just used 1 value, but this can be array of values resulted from DB
var opt = $('<option/>')
.attr('value', node+' - DB options') // note that the value is equal than the text
.text(node+' - DB options');
$('#hp_codes').append(opt);
});
});
});
</script>
</head>
<body>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">Hazard Statements: </label>
<span class="text-danger">*</span> </div>
<div class="mb-3 col-sm-8">
<select class="form-control select2" data-toggle="select2" id="hazards" name="hazards" multiple required>
<option value="H200">H200</option>
<option value="H201">H201</option>
<option value="H300">H300</option>
<option value="H301">H301</option>
<option value="H400">H400</option>
<option value="H410">H410</option>
</select>
</div>
</div>
</br>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">HP Codes: </label>
</div>
<div class="col-sm-8">
<select class="form-control" name="hp_codes" id="hp_codes" multiple readonly>
</select>
</div>
</div>
</body>
</html>
更接近您的原始代码,我相信这是需要的?
由于某些原因 #hazards
,addEventListener
没有触发,所以我改用 $('#hazards').on('change', ...
。
另外,似乎DOMContentLoaded
处理程序之后的所有代码都没有使用?
不管怎样,我添加了一个替代的唯一函数来过滤数组,commented-out,如果你觉得它有用的话。
// $(document).ready(function() {
// $('#hazards').select2();
// });
window.addEventListener('DOMContentLoaded', () => {
$('#hazards').select2();
let hprops = document.getElementById('hp_codes')
// document.querySelector('#hazards').addEventListener('change', e => {
// The hazards addEventListener was not firing?
$('#hazards').on('change', e => {
let options = e.target.options;
let hazards = [];
for (var i = 0, l = options.length; i < l; i++) {
if (options[i].selected) {
hazards.push(options[i].value);
}
}
hprops.innerHTML = '';
hprops.setAttribute('disabled', true); // disable until we get the data in there
// ajax to get actual data ...
let results = []
if (hazards.includes("H200") || hazards.includes("H201")) results.push('HP1')
if (hazards.includes('H300') || hazards.includes("H301")) results.push('HP6')
if (hazards.includes('H400') || hazards.includes("H410")) results.push('HP14')
results.forEach(r => hprops.innerHTML += `<option selected value="${r}">${r}</option>`)
hprops.removeAttribute('disabled');
})
})
// array_unique compressed:
function array_unique(d){var c="",b={},e="";var a=function(h,g){var f="";for(f in g){if(g.hasOwnProperty(f)){if((g[f]+"")===(h+"")){return f}}}return false};for(c in d){if(d.hasOwnProperty(c)){e=d[c];if(false===a(e,b)){b[c]=e}}}return b}
/* // an alternative unique
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
*/
var optionValues = [];
// $('#hp_codes').each(function() { // this removed the select!
$('#hp_codes').children().each(function() {
optionValues.push($(this).val());
$(this).remove(); // remove the option element
});
var cleanedArray = array_unique(optionValues); // clean the array
// var cleanedArray = optionValues.filter(onlyUnique); // clean the array
// let's go to paint the new options
for(var i in cleanedArray) {
var opt = $('<option/>')
.prop('value', cleanedArray[i]) // note that the value is equal than the text
.text(cleanedArray[i]);
$('#hp_codes').append(opt);
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">Hazard Statements: </label>
<span class="text-danger">*</span> </div>
<div class="mb-3 col-sm-8">
<select class="form-control select2" data-toggle="select2" id="hazards" name="hazards" multiple required>
<option value="H200">H200</option>
<option value="H201">H201</option>
<option value="H300">H300</option>
<option value="H301">H301</option>
<option value="H400">H400</option>
<option value="H410">H410</option>
</select>
</div>
</div>
</br>
<div class="row form-group">
<div class="col-sm-4">
<label class="control-label modal-label">HP Codes: </label>
</div>
<div class="col-sm-8">
<select class="form-control" name="hp_codes" id="hp_codes" multiple readonly>
</select>
</div>
</div>