Home > database >  Issue Initializing select2 dynamically
Issue Initializing select2 dynamically

Time:11-03

Select2 initializes for the first item generated with on click and then on generating new div item with on click the select2 property is removed from the first item and initializes on the 2nd.

$(document).ready(function(){

$("#packages #add_package").on("click", function(){
  $(this).before(
    "<div class='col-12 packageCard'>" 

        "<div class='col-4'>" 
          "<div class='form-group'>" 
            "<label>Container Type</label>" 
            "<select name='cntType' id='cntType' class='form-control select2' data-dropdown-css-class='select2' style='width: 100%;'>" 
              "<option value='0' selected='selected' disabled>Select Container Type</option>" 
              "<option>20 feet</option>" 
              "<option>40 feet</option>" 
            "</select>" 
        "</div>" 
      "</div>" 

  "</div>");
  $('.select2').select2();

  });
})

CodePudding user response:

If you check your browser's devtools console, you will see a Javascript error thrown when you try to add the second select2:

Uncaught query function not defined for Select2 undefined

If you search for that error, you will find some other questions about this, for eg this one: "query function not defined for Select2 undefined error"

And if you read through the answers and comments, you will find several which describe what you are doing:

This problem usually happens if the select control has already been initialized by the .select2({}) method. A better solution would be calling the destroy method first. Ex: $("#mySelectControl").select2("destroy").select2({});

One of its other possible sources is that you're trying to call select2() method on already "select2ed" input.

I also had this problem make sure that you don't initialize the select2 twice.

... and possibly more. These describe what you are doing - calling .select2() on elements which are already initialised as select2s. The second time $('.select2').select2() runs, as well as trying to initialise your new select2, it is re-initialising the first select2 as a select2 again.

You have another problem in your code - every select has the same ID: id='cntType'. IDs must be unique on the page, so this is invalid HTML.

We can solve both problems at once by keeping track of how many selects you have on the page, and giving each new one an ID including its number, like say cntType-1, cntType-2, etc. Then we can target just the new ID to initialise it as a select2.

Here's a working example.

$(document).ready(function () {
    
    // Track how many selects are on the page
    let selectCount = 0;
    
    $("#packages").on("click", function () {
        
        // New select!  Increment our counter
        selectCount  ;
        
        //. Add new HTML, using dynamically generated ID on the select
        $(this).before(
            "<div class='col-12 packageCard'>"  
            "<div class='col-4'>"  
            "<div class='form-group'>"  
            "<label>Container Type</label>"  
            "<select name='cntType' id='cntType-"   selectCount   "' class='form-control select2' data-dropdown-css-class='select2' style='width: 100%;'>"  
            "<option value='0' selected='selected' disabled>Select Container Type</option>"  
            "<option>20 feet</option>"  
            "<option>40 feet</option>"  
            "</select>"  
            "</div>"  
            "</div>"  
            "</div>");
        
        // Initialise only our new select
        $('#cntType-'   selectCount).select2();
    });
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.0.0/select2.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/2.1.0/select2.min.js"></script>

<button id="packages">Add</button>

  • Related