jQuery 初始化动态创建的 select2
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29972399/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Initialising select2 created dynamically
提问by Jason
I have a select2 drop-down for which I provide a matcher function. It is initialised like this on initial page load:
我有一个 select2 下拉列表,我为其提供了一个匹配器功能。它在初始页面加载时初始化如下:
jQuery(document).ready(function() {
jQuery(".my_select2").select2({
matcher: function(term, text) {...}
});
});
That works find on initial page load.
这可以在初始页面加载时找到。
Now, I have additional drop-downs (select
elements created dynamically (pulled in via AJAX, i.e. jQuery(match).load(url)
. These additional drop-downs do not get intialised as select2 widgets, which is understandable, even though they match the original select2 selector.
现在,我有额外的下拉菜单(select
动态创建的元素(通过 AJAX 拉入,即jQuery(match).load(url)
。这些额外的下拉菜单不会被初始化为 select2 小部件,这是可以理解的,即使它们与原始的 select2 选择器匹配。
So, how can I tell jQuery to treat these dynamically-created select
elements as select2 items that need to be initialised? Can I set some kind of "watch" on matching elements so the select2 initialisation kicks in every time a matching element gets added to the page?
那么,如何告诉 jQuery 将这些动态创建的select
元素视为需要初始化的 select2 项?我可以在匹配元素上设置某种“监视”,以便每次将匹配元素添加到页面时都会启动 select2 初始化吗?
I recall live()
being introduced in jQuery some time ago, that supported matching elements before they are created, if I understood it correctly. I never used that feature, and it now appears deprecated. But it does feel like the kind of thing I am looking for.
我记得live()
前段时间在 jQuery 中被引入,如果我理解正确的话,它在创建之前支持匹配元素。我从未使用过该功能,现在似乎已弃用。但这确实是我正在寻找的那种东西。
This is for a WordPress plugin, which uses jQuery v1.11.2 at present.
这是一个 WordPress 插件,目前使用 jQuery v1.11.2。
回答by Juan
you can try with DOMNodeInserted
and look for select or the class you're assigning them
你可以尝试 DOMNodeInserted
寻找选择或你分配给他们的班级
$('body').on('DOMNodeInserted', 'select', function () {
$(this).select2();
});
Update
更新
DOMNodeInserted
DOMNodeInserted
DeprecatedThis 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;
已弃用此功能已从 Web 标准中删除。虽然一些浏览器可能仍然支持它,但它正在被删除。尽可能避免使用它并更新现有代码;
The suggested method would be something like this with MutationObserver
建议的方法是这样的 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>
回答by roshan
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.
在 .load 函数的情况下,找到所有要在 load 函数的回调中初始化的选择元素,并在每个选择元素上调用 initializeSelect2。
I hope this helps someone who is looking for a simple solution.
我希望这对正在寻找简单解决方案的人有所帮助。
回答by Уляна Р?зник
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>
回答by mourya venkat
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.
因此,当第一次加载 DOM 时,无论加载什么选择项都将具有 select2 功能,对于动态生成的字段 select2 功能将不可用,因为 select2 脚本已经加载。
So to make the select2 work, reload the scripts dynamically on click.
因此,要使 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();
})
})
})
}
What this does is, it adds the select2 functionality to $.
它的作用是将 select2 功能添加到 $.
回答by Kyle Coots
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'));
});
回答by DaveN
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.
我解决了类似于 roshan 的解决方案,但没有在函数中传递选择对象。这是用于 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));
}
});
};
Sorry for leaving in the extraneous stuff - I commented on areas of interest. Hope this helps others!
很抱歉留下无关的东西 - 我评论了感兴趣的领域。希望这对其他人有帮助!