Initialising select2 created dynamically

前端 未结 6 1731
孤独总比滥情好
孤独总比滥情好 2020-12-01 04:49

I have a select2 drop-down for which I provide a matcher function. It is initialised like this on initial page load:

jQuery(document).ready(function() {
             


        
相关标签:
6条回答
  • 2020-12-01 05:15

    I worked this out similar to roshan's solution, but didn't pass the select object in the function. This is for a table output from an ajax call.

    $(document).ready(function() {
    
            function initSelect2() {
                $("[id^='DDAlertFreq']").select2({
                    minimumResultsForSearch: Infinity,
                    allowClear: false,
                    theme: "bootstrap"
                });
            };
    
    //define the dropdown and set to variable    
    var DDAlertFrequency = '<select id="DDAlertFreq" ><option value="Fifteen_Minutes">15 Minutes</option><option value="Thirty_Minutes">30 Minutes</option><option value="Hour">Hour</option><option value="Two_Hours">2 Hours</option><option value="Three_Hours">3 Hours</option><option value="Four_Hours">4 Hours</option><option value="Six_Hours">6 Hours</option><option value="Eight_Hours">8 Hours</option><option value="Twelve_Hours">12 Hours</option><option value="Day">Day</option></select>'
    
    function RetrieveUserAlerts(uid) {
                    $.ajax({
                        url: 'SavedSearches.asmx/LoadUserAlerts',
                        dataType: 'json',
                        method: 'post',
                        data: { userid: uid },
                        success: function (data) {
                            var tbl = $("#tblAlerts > tbody");
                            tbl.empty();
                            $.each(data, function () {
                                userAlert.alert_idx = this['alert_idx'];
                                userAlert.Name = this['Name'];
                                userAlert.price_alert_low = this['price_alert_low'];
                                userAlert.alert_frequency = this['alert_frequency'];
                                userAlert.alert_max_per_day = this['alert_max_per_day'];
                                userAlert.alert_to_email = this['alert_to_email'];
                                userAlert.alert_to_sms = this['alert_to_sms'];
                                userAlert.active = this['active'];
                                userAlert.alert_start_date = moment(this['alert_start_date']).format("MM/DD/YY");
                                userAlert.alert_end_date = moment(this['alert_end_date']).format("MM/DD/YY");
                                userAlert.OpenSectionID = this['OpenSectionID'];
    // modify the dropdown to assign unique id and match selection
                                var selectAlert = DDAlertFrequency.replace("DDAlertFreq", "DDAlertFreq_" + userAlert.alert_idx).replace('"' + userAlert.alert_frequency + '"', '"' + userAlert.alert_frequency + '" selected');
                                var tblRow = '<tr><td>'
                                    + userAlert.Name
                                 + '</td><td>'
                                + '<input id="txtPriceAlertLow_' + userAlert.alert_idx + '" type="text" class="form-control" value="' + userAlert.price_alert_low + '"/>'
                                 + '</td><td>'
                                + '<input id="chkAlertToEmail_' + userAlert.alert_idx + '" type="checkbox" ' + ((userAlert.alert_to_email == true) ? "checked" : "") + ' />'
                                 + '</td><td>'
                                + '<input id="chkAlertToEmail_' + userAlert.alert_idx + '" type="checkbox" ' + ((userAlert.alert_to_sms == true) ? "checked" : "") + ' />'
                                 + '</td><td>'
                                + selectAlert //modified Select2 dropdown
                                 + '</td><td>'
                                 + '<input id="txtMaxPerDay_' + userAlert.alert_idx + '" type="text" class="form-control" value="' + userAlert.alert_max_per_day + '"/>'
                                 + '</td><td>'
                                + userAlert.alert_start_date
                                 + '</td><td>'
                                + userAlert.alert_end_date
                                 + '</td><td>'
                               + '<input id="chkActive_' + userAlert.alert_idx + '" type="checkbox" ' + ((userAlert.active == true) ? "checked" : "") + ' />'
                                 + '</td><tr>'
                                tbl.append(tblRow);
                                initSelect2(); //call the function to initialize all Select2 dropdowns created
                            });
                        },
                        error: function (err) {
                            console.log('Error (RetrieveUserAlerts): ' + JSON.stringify(err, null, 2));
                        }
                    });
                };
    

    Sorry for leaving in the extraneous stuff - I commented on areas of interest. Hope this helps others!

    0 讨论(0)
  • 2020-12-01 05:17

    Similar to above answer:

    function initSelect2(element){
      element.select2({   });
    }
    
    // Dynamic add 
    $('button[data-id="add-item"]').on('click', function(){
       // Add element
       obj.addItem();
       // Add Select2 to element
       initSelect2($('element'));
    });
    
    0 讨论(0)
  • 2020-12-01 05:22

    you can try with DOMNodeInserted and look for select or the class you're assigning them

    Demo

    $('body').on('DOMNodeInserted', 'select', function () {
        $(this).select2();
    });
    

    Update

    DOMNodeInserted

    Deprecated This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped. Avoid using it and update existing code if possible;

    The suggested method would be something like this with MutationObserver

    $(function() {
      $("button").on("click", function() {
        $("#dynamic-container").append($("<select><option>test</option><select/>"));
      });
    
      // select the target node
      var target = document.getElementById('dynamic-container');
    
      if (target) {
        // create an observer instance
        var observer = new MutationObserver(function(mutations) {
          //loop through the detected mutations(added controls)
          mutations.forEach(function(mutation) {
          //addedNodes contains all detected new controls
            if (mutation && mutation.addedNodes) {
              mutation.addedNodes.forEach(function(elm) {
              //only apply select2 to select elements
                if (elm && elm.nodeName === "SELECT") {
                  $(elm).select2();
                }
              });
            }
          });
        }); 
        
        // pass in the target node, as well as the observer options
        observer.observe(target, {
          childList: true
        });
    
        // later, you can stop observing
        //observer.disconnect();
      }
    });
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet"/>
    <script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
    
    
    <button>Add new select</button>
      <div id="dynamic-container">
    
      </div>

    0 讨论(0)
  • 2020-12-01 05:23

    I have faced the same issue, But after scratching my head for days, I found a solution but its not good if you expect good performance.

    So when DOM loaded for first time, whatever select items are loaded will have select2 functionality, For dynamic generated fields select2 functionality wont be available because the select2 scripts are already loaded.

    So to make the select2 work, reload the scripts dynamically on click.

    function reload(id) {
        $(id).on("click", function () {
            $("head").append($("<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.css' type='text/css' media='screen' />"));
            $.getScript("https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js", function () {
                $.getScript("https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.min.js", function () { 
                    $('select').select2();
                })
            })
        })
    }
    

    What this does is, it adds the select2 functionality to $.

    0 讨论(0)
  • 2020-12-01 05:26

    I came across a similar situation recently but did it in a very usual way:

    $(document).ready(function() {
    
     //function to initialize select2
      function initializeSelect2(selectElementObj) {
        selectElementObj.select2({
          width: "80%",
          tags: true
        });
      }
    
    
     //onload: call the above function 
      $(".select-to-select2").each(function() {
        initializeSelect2($(this));
      });
    
     //dynamically added selects
    
      $(".add-new-select").on("click", function() {
        var newSelect = $("<select class='select-to-select2'  multiple><option>option 1</option><option>option 2</option></select>");
        $(".select-container").append(newSelect);
        initializeSelect2(newSelect);
      });
    
    
    });
    <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.css" rel="stylesheet" />
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.min.js"></script>
    <div class="select-container">
      <select class='select-to-select2' multiple>
        <option value='1'>option1</option>
        <option value='2'>option2</option>
      </select>
    
      <select class='select-to-select2' multiple>
        <option value='1'>option1</option>
        <option value='2'>option2</option>
      </select>
    
    </div>
    <div>
      <button class="add-new-select">Add New Select</button>
    </div>

    In case of the .load function find all the select elements which are to be initialized in the callback of load function and call initializeSelect2 on each of those select elements.

    I hope this helps someone who is looking for a simple solution.

    0 讨论(0)
  • 2020-12-01 05:27

    It works for me

    <div id="somediv">
        <select class="component">
        ...
        </select>
    </div>
    
    
    
    <script>
        $(document).on('click', '#addComponent', function () {
    
            $('#somediv').append(data); //data is my new select
            $('.component:last').select2();
        });
    </script>
    
    0 讨论(0)
提交回复
热议问题