How to initialize select2 dynamically
Asked Answered
G

2

8

I insert rows of concepts (with select and input text elements) in my DOM through AJAX. And I want to initialice those select to select2: but I don't know the proper way to do that.

  • I should write the javascript in each row? (Insert html and JS through AJAX)

I get this in each AJAX request:

<select id="concept0"> 
    <option value="Test"> Test </option>
    <option value="Test2"> Test 2 </option>    
</select>
<script> $("#concept0").select2(); </script>

But I think is a wrong idea to return the javascript with the HTML in my AJAX response. There are other alternative?

Thanks and sorry if my question is a little stupid...

Gsuit answered 7/10, 2015 at 4:56 Comment(11)
Write your code here what you triedInflect
Ok. Sorry I will write it in few minutesGsuit
I send a counter in each AJAX request, so this works well... But I think this isn't the right way to do that...Gsuit
ID must be unique in page. Add class to the selects and use unique ids. Then call .select2(); using class name in the AJAX callback.Ulda
you should use ajax for this, onchange in first select, call ajax and fetch values for second select.Jihad
@RejithRKrishnan My IDs are uniques. As i said in my comment I send a incremental counter and in PHP i compose the ID with the counter... But i dont know if is correct to return javascript and html from PHP...Gsuit
@NiranjanNRaju I use AJAX. I have a button "addConcept"Gsuit
With "addConcept" I add the concepts dynamically (AJAX) so I dont need the onchange event.Gsuit
No, I only want to know how is the proper way to initializate a select2 dynamically. My method (return HTML and javascript in AJAX response) seems ugly...Gsuit
show your ajax part..Mazzola
after adding some concepts in ajax to db, you want to add the value to your select dropdown ??Jihad
W
3

I would construct the flow like this :

  • Group the partials selects to reduce the number of Ajax requests
  • Add markers to the partial HTML with 'data-'
  • Retrieve partial html with AJAX GET;
  • Initialize elements;
  • [Optionally] Detach the target parent element - performance reasons;
  • Append elements to the target;
  • [Optionally] Reattach the target element;
  • Initialize the widgets.

I've made a simulation here : http://jsbin.com/jotitu/edit?js,output

Bellow is a little explanation:

So lets say you have the following HTML:

<div id="concept-table-container">
 <table>
   <tr>
     <th>
        No.
     </th>
     <th>
        Name.
     </th>
     <th>
        Option.
     </th>
   </tr>
   <tr>
     <td>1</td>
     <td>abc</td>
     <td></td>
   </tr>
   <tr>
     <td>2</td>
     <td>dce</td>
     <td></td>
   </tr>
   <tr>
     <td>3</td>
     <td>fgh</td>
     <td></td>
   </tr>
 </table>
</div>

Group the partials selects to reduce the number of Ajax requests and add markers to the partial HTML with 'data-'

If you can group and write your partial HTML like this you won't need to do to an Ajax request for each row. You can chose to limit them also, but that requires a bit more programming for "pagination".

<select data-widget="select2" data-row-idx="0"> 
    <option value="Test"> Test </option>
    <option value="Test2"> Test 2 </option>    
</select>
<select data-widget="select2" data-row-idx="1"> 
    <option value="Test"> Test </option>
    <option value="Test2"> Test 2 </option>    
</select>
<select data-widget="select2" data-row-idx="2"> 
    <option value="Test"> Test </option>
    <option value="Test2"> Test 2 </option>    
</select>

Retrieve partial html with AJAX GET

I won't get here into the details, it's enough to say that :

$.get(conceptPartialUrl, successCallback);

Initialize elements;

var successCallback = function(data){
  var $fragmentEl = initEls(data);
  // Optionally before appending the selects detach the container;
  appendElements($fragmentEl, $containerEl);
  // Initialize the widgets.
  initSelect2Widgets();
};


var initEls = function(data){
  // Create DOM elements - JQuery Way
  var $fragmentEl = $(data);
  // Return the reference
  return $fragmentEl;
};

Append elements to the target;

var appendElements = function($fragmentEl, $containerEl){
   var $rows = $containerEl.find('tr');
   $fragmentEl.each(function(){     
      var $el = $(this);


      // some matching - you 
      var idx = $el.data('row-idx');

      // that plus 1 is to skip the header        
      // find the row         
      var $row = $rows.eq(idx+1);         
      // find the cell, empty it and append the element  
      $row .find('td').last().text('').append($el);
   });
};

Initialize the widgets

var initSelect2Widgets = function(){
  $containerEl.find('[data-widget="select2"]').select2();
};
Wismar answered 7/10, 2015 at 5:51 Comment(0)
L
3

I have got another way around for this :

As you said in your comment that you send a counter in each ajax request (I hope that you are using that counter to generate id of select), you can store that in some element or js variable before ajax request. So that at every ajax request you have that unique value of counter.

Than you can initialize you select2 using :

$(document).ajaxComplete(function() {
    $(document).find('your-unique-counter-select-id').select2();
});
Ldopa answered 7/10, 2015 at 7:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.