初始化动态创建的select2

时间:2015-04-30 15:54:35

标签: jquery jquery-select2

我有一个select2下拉列表,我提供了一个匹配器功能。它在初始页面加载时初始化为:

jQuery(document).ready(function() {
    jQuery(".my_select2").select2({
        matcher: function(term, text) {...}
    });
});

可以找到初始页面加载。

现在,我有额外的下拉列表(select元素动态创建(通过AJAX拉入,即jQuery(match).load(url)。这些额外的下拉列表不会像select2小部件那样被初始化,这是可以理解的,即使它们与原来的select2选择器匹配。

那么,我如何告诉jQuery将这些动态创建的select元素视为需要初始化的select2项?我可以设置一些" watch"在匹配元素上,所以每次匹配元素添加到页面时,select2初始化都会启动吗?

我记得前一段时间在jQuery中引入live(),如果我理解正确的话,它会在创建之前支持匹配元素。我从未使用过该功能,现在看来已弃用。但它确实感觉像我正在寻找的那种东西。

这是一个WordPress插件,目前使用jQuery v1.11.2。

6 个答案:

答案 0 :(得分:24)

您可以尝试使用DOMNodeInserted并查找您为其分配的精选课程

<强> Demo

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

<强>更新

DOMNodeInserted

  

<强>已过时   此功能已从Web标准中删除。虽然有些浏览器可能仍然支持它,但它正在被删除。如果可能,请避免使用它并更新现有代码;

建议的方法与MutationObserver

类似

&#13;
&#13;
$(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();
  }
});
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:14)

我最近遇到了类似的情况,但是以一种非常平常的方式做到了:

$(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>

如果.load函数找到所有要在load函数的回调中初始化的select元素,并在每个select元素上调用initializeSelect2。

我希望这有助于寻找简单解决方案的人。

答案 2 :(得分:3)

它对我有用

<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>

答案 3 :(得分:0)

我也遇到过同样的问题,但是经过几天的努力,我找到了一个解决方案,但是如果您希望获得良好的性能,那就不好了。

因此,当第一次加载DOM时,无论加载什么选择项都将具有select2功能,对于动态生成的字段,select2功能将不可用,因为select2脚本已经加载。

因此,要使select2正常工作,请在单击时动态重新加载脚本。

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();
            })
        })
    })
}

这是什么,它将select2功能添加到$。

答案 4 :(得分:0)

类似于以上答案:

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'));
});

答案 5 :(得分:-1)

我的工作方式类似于roshan的解决方案,但没有传递函数中的select对象。这是针对ajax调用的表输出。

$(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));
                    }
                });
            };

很抱歉留下无关紧要的东西 - 我评论了感兴趣的领域。 希望这有助于他人!