Daniel Bednář
Daniel Bednář

Reputation: 142

Select2 select all elements after opening

I have select2 and need to document.querySelectorAll all items of the select2 after opening. I can't select them before opening, because the container with items isn't generated before click. All my select2 items have class select2-item. I'm trying to handle this by using .on("select2:opening"), but no data will be in my variable.

$("#select").on("select2:opening", function(){
   selectAllItems();
});

function selectAllItems(){
    const items = document.querySelectorAll(".select2-item");

    console.log(items);
    console.log(JSON.stringify(items));
}

The output is

NodeList []
    length: 0

{}

Version of Select2 is 4.0.5.

Upvotes: 2

Views: 910

Answers (2)

Jason Roman
Jason Roman

Reputation: 8276

Based on your comment of wanting all the <li> items, you would normally do this inside your selectAllItems() function, as the dynamically-generated list is contained within a <span> element that has the class .select2-container.

const items = $('.select2-container li');

However, if you call this function immediately on the select2:opening event, the list will not have been generated yet. You can instead put in a very small delay of say, 100 ms which will give enough time for the list to be generated, and then you can select the items within. This should work for you:

function selectAllItems() {
  const items = $('.select2-container li');
  console.log('items', items);
}

$(function() {
  $('#select').select2();
  
  $('#select').on('select2:opening', function (e) {
    setTimeout(selectAllItems, 100);
  });
});

I tried using the select2:open event without a timeout, but that produced a single <li> for loading results which isn't correct. Using select2:open with the same 100 ms timeout did work though.

I will say that it is unusual to want to work on the list items directly - select2 allows you to work on the original <select> list and <option> elements and that is what you should strive to interact with. The above code will work for what you asked for, but I would not work on those <li> DOM elements individually unless you had a very specific reason.

Upvotes: 1

ash
ash

Reputation: 514

try the following

$("#select").on("select2:opening", function(){
   let items = $('option:selected', this).val();
    selectAllItems(items);
});

function selectAllItems(items){
    
    console.log(items);
    console.log(JSON.stringify(items));
}

Upvotes: 0

Related Questions