Select2 dosen't work when I append it using JavaScript function

Hi there! I am trying to make a sales page where user can select products in multiple rows so the select3 in rows which are present when page load works fine but whenever I try to add a new row which has a select2 dropdown doesn’t display a search box. you can see the screenshot below:

and this is my code to insert a new row:

   $(document).on('click', '#add_row', function(){
   count++;
   $('#total_item').val(count);
  var html_code = '';
  html_code += '<tr id="row_id_'+count+'">';
  html_code += '<td><span id="sr_no">'+count+'</span></td>';
  html_code += '<td data-select2-id="'+(count * 50)+'">'+
                  '<div class="form-group">'+
                    '<select class="form-control select2" style="width: 100%;" id="product-name'+count+'" name="product_name[]">'+
                      '<option selected="selected" disabled>Select Product</option>'+
                      <?php foreach($rows as $row){ ?>
                        '<option value="<?php echo($row["product_id"]); ?>"><?php echo($row["product_id"]); ?> | <?php echo($row["product_name"]); ?></option>'+
                      <?php } ?>
                    '</select>'+
                  '</div>'+
                '</td>';
  html_code += '<td> <input type="text" name="rate[]" id="rate1"  class="form-control"> </td>';
  html_code += '<td> <input type="number" name="qty[]" id="qty1" min="1" class="form-control"> </td>';
  html_code += '<td> <input type="text" name="amount[]" id="amount1" class="form-control"> </td>';
  html_code += '<td> <input type="text" name="disc[]" id="disc1" value="0" class="form-control"> </td>';
  html_code += '<td> <input type="text" name="total[]" id="total1" class="form-control"> </td>';
  html_code += '<td> <div class="btn-group btn-group-sm"> <button type="button" onclick="removeRow()" class="btn btn-danger"><i class="fas fa-trash"></i></button> </div> </td>';

  $('#items-list').append(html_code);

});
  });

and this is how I am initializing select2:

$('.select2').select2()

Please let me know what is the right way to do that. Thanks in advance!

Every time you add a new row, you must initialize the Select2 in that row. When you call $('.select2').select2() after page load, that only initializes the Select2s that exist in the HTML page at that time. Any other Select2’s you add after that must be initialized individually. I would recommend you give each new row’s <select> a unique id attribute so you can target just that specific <select> in your $.select2() call; otherwise you will re-initialize all of the Select2’s on the page every time to add a new row, and that will reset any selections in any of the previous Select2s.

(Also, I think your post is missing some HTML; for instance, I don’t see the <select> element you’re adding to each row; I only see the PHP code to generate the <option> elements. If you will put your inside triple-backticks, like this:
```
your code goes here…
```
it will preserve line breaks and indents and make your code easier to read.)

2 Likes

Sorry I didn’t reviewed my code. Please take a look at this again and also how can I initialize the Select2 in newly inserted row?

Just add the following below this line:

$('#items-list').append(html_code);
/* Add the line below to your code: */
$('#' + product-name' + count, '#items-list').select2();

The new line of code finds the new <select> element you just appended and calls the .select2() initialization method on it.

4 Likes

Thank you sir! You saved my life :smiley:

Great, Explanation buddy. U saved my day.

@John30013 can you please have a look into below script.
html input:

Adding below line behaves abnormal and it does not allow to change option
// $(’#isic4select’).html("");
$.ajax({
url: config.routes.isic4catwactivity,
type: “POST”,
dataType: “json”,
async: “false”,
data: { ‘id’: isic4_main_id },
headers: { ‘X-CSRF-TOKEN’: $(‘meta[name=“csrf-token”]’).attr(‘content’) },

        success: function(data) {

            if (data.status) {                    
                var options = '<option>'+isic4_main_val+'</option>';

                $(data.lists).each(function(inx, val) {

                    if(val.activities.length){
                        options +='<optgroup id="'+val.id+'" label="'+val.category_name+'">';

                        $(val.activities).each(function(index, activity) {
                            options +='<option value="'+activity.id+'">'+activity.activity_name+' - '+activity.activity_code+'</option>';

                        });

                        options +='</optgroup>';

                    }
                
                });
            }

            if(options != "")
                $("#isic4select").append(options);                

        }

    });

Note: My requirement is to remove all the options and populate them dynamically