【问题标题】:Select2 multiselect options to display options in another multiselectSelect2 多选选项以在另一个多选中显示选项
【发布时间】:2022-02-01 11:51:30
【问题描述】:

我刚刚将我的一个多选切换到 select2,因为我之前的复选框多选与我的新页面模板 CSS 不兼容,并且看起来非常不合适。

在第一个多选(现在是select2)中,用户可以选择他们过多的选项,下面的第二个多选将填充与第一个已经选择的相关选项和字段读取的相关选项只要。这以前工作得很好,但现在不再这样做了。

这是我正在使用的代码。 select2hazards 的选项是从按预期工作的数据库中提取的。

$(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>

【问题讨论】:

  • 请尝试使用不涉及 PHP 代码的示例制作可运行的堆栈 sn-p。使用编辑器工具栏上的&lt;&gt; 图标。对于 HTML,需要从 sn-p 编辑器的左侧为 sn-p 的 HTML 部分选择 jquery。
  • @PaulT。干杯 - 我已经编辑了 OP 以包含一个 sn-p。

标签: javascript html jquery jquery-select2


【解决方案1】:

保持更接近您的原始代码,我相信这是需要的吗? 由于某种原因,addEventListener 没有为#hazards 触发,所以我改用了$('#hazards').on('change', ...

另外,似乎DOMContentLoaded 处理程序之后的所有代码都没有使用?
无论如何,我添加了一个替代的独特函数来过滤数组,如果你觉得它有用的话,请注释掉。

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

【讨论】:

  • 工作完美,谢谢!
【解决方案2】:

简化您的代码并放置核心逻辑来触发更改。这将自动对危险选项中的任何选择或删除做出反应。

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

【讨论】:

  • 感谢您的回答。我不确定这是否会实现我想要做的事情(或者它曾经做过的事情)。危险存储在数据库中,而 HP 代码不是 - 这些是直接从原始 javascript 中获取的,然后 HP 代码 mutliselect 字段将显示不包括危险的单独选项。我已经编辑了 OP 以包含没有 select2 和 JQuery 的情况。
猜你喜欢
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2016-09-18
  • 2020-07-19
  • 2019-02-10
相关资源
最近更新 更多