最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Order of Select2 selection based on array of items - Stack Overflow

programmeradmin0浏览0评论

I'm trying to set the order of selected items in Select2 based on an array.

A simple solution has already been proposed to append items in the order with which they are clicked in the dropdown menu (see 2rba's answer on 2017-10-26 in this discussion):

        $("#selectCriteria").on("select2:select", function (evt) {
          var element = evt.params.data.element;
          var $element = $(element);
          $element.detach();
          $(this).append($element);
          $(this).trigger("change");
    });

What I'm trying to do is mimick this behavior, but when passing an array of the selected items instead of manually clicking them in the list. I tried the following mand:

displayed_items = ["b", "c", "a"];  
$('#selectCriteria').val(displayed_items).trigger('change'); 

But the order isn't preserved. I tried looping the mand with one element at a time, but each new call overwrites the previous element:

 $('#selectCriteria').val("b").trigger('change'); 
 $('#selectCriteria').val("c").trigger('change'); 
 $('#selectCriteria').val("a").trigger('change'); 

I see two possible solutions to this, but lack the background to make them work:

  1. How should the iteration above be adapted to not overwrite the previously added value?
  2. How could I incorporate the approach shown in this fiddle (from vol7ron's posts on github) which does pretty much what I'm asking (i.e. toggling on/off the .data('preserved-order',selected))? As it is using JSX I'm not sure how I could reuse that script in my plain JS/jQuery script.

I'm trying to set the order of selected items in Select2 based on an array.

A simple solution has already been proposed to append items in the order with which they are clicked in the dropdown menu (see 2rba's answer on 2017-10-26 in this discussion):

        $("#selectCriteria").on("select2:select", function (evt) {
          var element = evt.params.data.element;
          var $element = $(element);
          $element.detach();
          $(this).append($element);
          $(this).trigger("change");
    });

What I'm trying to do is mimick this behavior, but when passing an array of the selected items instead of manually clicking them in the list. I tried the following mand:

displayed_items = ["b", "c", "a"];  
$('#selectCriteria').val(displayed_items).trigger('change'); 

But the order isn't preserved. I tried looping the mand with one element at a time, but each new call overwrites the previous element:

 $('#selectCriteria').val("b").trigger('change'); 
 $('#selectCriteria').val("c").trigger('change'); 
 $('#selectCriteria').val("a").trigger('change'); 

I see two possible solutions to this, but lack the background to make them work:

  1. How should the iteration above be adapted to not overwrite the previously added value?
  2. How could I incorporate the approach shown in this fiddle (from vol7ron's posts on github) which does pretty much what I'm asking (i.e. toggling on/off the .data('preserved-order',selected))? As it is using JSX I'm not sure how I could reuse that script in my plain JS/jQuery script.
Share Improve this question asked Nov 17, 2017 at 15:22 sc28sc28 1,2136 gold badges28 silver badges52 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

here you go

EDIT:

this is not the prettiest solution, but it gets the job done.

you would have to call initSelect function that takes an array of values as a parameter. i left some ments in the code.

displayed_items = $('#selected_items').val().split(',');
    
function selectItem(target, id) { // refactored this a bit, don't pay attention to this being a function
  var option = $(target).children('[value='+id+']');
  option.detach();
  $(target).append(option).change();
} 

function customPreSelect() {
  let items = $('#selected_items').val().split(',');
  $("select").val('').change();
  initSelect(items);
}

function initSelect(items) { // pre-select items
  items.forEach(item => { // iterate through array of items that need to be pre-selected
    let value = $('select option[value='+item+']').text(); // get items inner text
    $('select option[value='+item+']').remove(); // remove current item from DOM
    $('select').append(new Option(value, item, true, true)); // append it, making it selected by default
  });
}

$('select').select2();
$('select').on('select2:select', function(e){
  selectItem(e.target, e.params.data.id);
});

initSelect(displayed_items); // call init
select {
  width: 50%;
}

.container {
  display: flex;
  flex-direction: column;
}

.control-group {
  padding-bottom: 1em;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare./ajax/libs/select2/4.0.4/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare./ajax/libs/select2/4.0.4/js/select2.min.js"></script>

<div class="container">

  <p>Provide ma separated items to be pre selected and click the button</p>
  <div class="control-group">
    <input id="selected_items" value="b,c,a"/>
    <button onclick="customPreSelect()">Init</button>
  </div>

  <select multiple="multiple">
    <option value="a">A</option>
    <option value="b" >B</option>
    <option value="c">C</option>
    <option value="d">D</option>
  </select>
</div>

This preserves attributes of the select2 options (e.g. titles used for tooltips):

function initSelect(items) {
    items.forEach(item => {
        var option = $('#selectCriteria').children('[value="' + item + '"]');
        option[0].selected = true;
        option.detach();
        $('#selectCriteria').append(option).change();
    })
}
发布评论

评论列表(0)

  1. 暂无评论