jQuery 使用 WordPress 选择 2
jQuery select2 with WordPress
我在 WordPress 中使用 jQuery select2。
我有一个HTMLtable这样的
如果用户点击 Bob SMith and admin
,我需要这里,它将转换为具有多个 select.
的 select2
下拉菜单
但是当我点击它时,它看起来像下面
如果我再次单击,下拉菜单将如下所示。
当我点击任何值时,它看起来像下面
我的jQuery代码如下
(function($) {
var states = [];
$(document).ready(function() {
$(".volunteer").on("click", function(event) {
// Check if select is already loaded
if (!$(this).has("select").length) {
var cellEle = $(this);
var cellId = this.id;
// Populate select element
cellEle.html(`<select class="js-example-basic-multiple" multiple="multiple">
<option value="AL">Alabama</option>
<option value="WY">Wyoming</option>
</select>`);
// Initialise select2
let selectEle = cellEle.children("select").select2();
if(states[cellId]){
// preselect existing value
selectEle.val(states[cellId]);
selectEle.trigger('change');
}
selectEle.on("select2:close", function(event) {
// Get selected value
selectedValue = selectEle.select2('data')[0]['text'];
// Update array
states[cellId] = selectedValue.id;
// Destroy select2
selectEle.select2('destroy');
// Change html to just show the value
cellEle.html(selectedValue.id);
});
}
});
});
})(jQuery)
我的HTML代码如下
<td class="volunteer" id="47">Bob SMith and admin</td>
点击两次
第一次点击单元格会初始化 select2,第二次点击会告诉 select2 显示下拉列表。要只需要单击一次,您可以在初始化 select2 后调用 https://select2.org/programmatic-control/methods 中描述的打开方法。
// Initialise select2
let selectEle = cellEle.children("select").select2();
// Open the select2 dropdown
selectEle.select2('open');
替换Select
当点击值 select2 被销毁时,.html()
调用应将 select 替换为 selected 值,但它不起作用正确,因为 id
属性 在存储值中不存在,这导致单元格恢复为正常 select.
处理 "select2:close"
事件的代码包含 selectedValue = selectEle.select2('data')[0]['text'];
行,它将第一个 selected 值 [0]
的文本放入变量 selectedValue
。在此之后,使用 cellEle.html(selectedValue.id);
更新单元格的 HTML,但此时 selectedValue
仅包含文本(例如“Alabama”),因此没有 .id
属性。要解决此问题,可以将 ID 和文本都存储在数组中,然后在需要的地方使用,例如:
// Store the id and text of all selected values in the array
selectedValue = selectEle.select2('data').map(function(value) {
return { id: value.id, text: value.text };
});
// Get an array of IDs for the selected values (for preselecting values when select2 loads)
selectEle.val(states[cellId].map(function(value) { return value.id })).trigger('change');
// Get a comma separated string of the selected values (for populating the text in the cell)
cellEle.html(states[cellId].map(function(value) { return value.text; }).join(','));
多 Select 模式 -
允许多个 select 离子的示例是 https://jsfiddle.net/aqgbxz1d/ 并且也包含在下面的这个答案中。这似乎是基于问题中 multiple="multiple"
属性 的所需模式。
示例已更新,不再使用 select2:close
事件。相反,它使用 change
事件来存储值更改,并在文档上使用第二个 click
事件处理程序来在用户单击页面上的其他位置时销毁 select2 下拉列表.考虑到您要实现的目标,这似乎是一种更好的方法,因为它使 select 对多个值开放 selected。
单Select模式 -
从评论来看,似乎可能需要单一 select 模式。一个只允许一个 selection 的例子是 https://jsfiddle.net/9jcnwbt2/1/。如果需要单一 select 模式,那么您需要:
- 删除多重属性
multiple="multiple"
- 添加一个空白选项
<option></option>
- 您还可以复制文档点击事件中的代码,该事件会破坏 select2 并将 HTML 更新为更改事件。
(function ($) {
var states = [];
$(document).ready(function () {
$(".volunteer").on("click", function (e) {
// Check if select is already loaded
if (!$(this).has("select").length) {
var cellEle = $(this);
var cellId = this.id;
// Populate select element
cellEle.html(`<select class="js-example-basic" multiple="multiple">
<option value="AL">Alabama</option>
<option value="WY">Wyoming</option>
</select>`);
// Initialise select2
let selectEle = cellEle.children("select").select2({placeholder: "Select a value"});
// Open the select dropdown so user doesn't have to click twice
selectEle.select2('open');
// Check if there is an existing value for this cell
if (states[cellId]) {
// preselect existing value
selectEle.val(states[cellId].map(function (value) {
return value.id
})).trigger('change');
}
// Attach event handler to store value changes
selectEle.on('change', function (e) {
// Get selected values
selectedValues = $(this).select2('data');
// Update the states array with id and text of selected
// values. The id is needed to restore the values if select2
// is reloaded on this cell. The text is required to generate
// the replacement text shown in the cell
states[cellId] = selectedValues.map(function (value) {
return {
id: value.id,
text: value.text
};
});
});
}
// Don't propagate the event
// This prevents this document click handler from executing which would
// remove select2 by calling destroy
e.stopPropagation();
});
});
// Attach event handler to document to capture any clicks
// This will be triggered for all clicks on the page, except those
// captured by the method described above this prevents this firing
// with e.stopPropagation()
// Which this is called select2 on any cells must be destoryed and their
// text value populated
$(document).on('click', function (e) {
// Loop through all select2 elements
$('.js-example-basic').each(function (idx) {
// Get the ID of the cell that's been selected
let cellId = $(this).parent().attr('id');
// Destroy select2 on this element
$(this).select2('destroy');
// Change html on the parent element (td) to just show the value
if(states[cellId] && states[cellId].length > 0){
$(this).parent().html(states[cellId].map(function (value) {
return value.text;
}).join(','));
} else {
$(this).parent().html("Select a value...")
}
});
});
})(jQuery)
.js-example-basic {
width: 200px;
}
thead{
font-weight: bold;
}
table, th, td {
border: 1px solid black;
}
tr {
height: 36px;
}
td {
width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<table>
<thead>
<tr>
<td>Table Header 1</td>
<td>Table Header 2</td>
</tr>
</thead>
<tbody>
<tr>
<td class="volunteer" id="47">Select a value...</td>
<td class=""></td>
</tr>
<tr>
<td class="volunteer" id="48">Select a value...</td>
<td class=""></td>
</tr>
</tbody>
</table>
我在 WordPress 中使用 jQuery select2。
我有一个HTMLtable这样的
如果用户点击 Bob SMith and admin
,我需要这里,它将转换为具有多个 select.
select2
下拉菜单
但是当我点击它时,它看起来像下面
如果我再次单击,下拉菜单将如下所示。
当我点击任何值时,它看起来像下面
我的jQuery代码如下
(function($) {
var states = [];
$(document).ready(function() {
$(".volunteer").on("click", function(event) {
// Check if select is already loaded
if (!$(this).has("select").length) {
var cellEle = $(this);
var cellId = this.id;
// Populate select element
cellEle.html(`<select class="js-example-basic-multiple" multiple="multiple">
<option value="AL">Alabama</option>
<option value="WY">Wyoming</option>
</select>`);
// Initialise select2
let selectEle = cellEle.children("select").select2();
if(states[cellId]){
// preselect existing value
selectEle.val(states[cellId]);
selectEle.trigger('change');
}
selectEle.on("select2:close", function(event) {
// Get selected value
selectedValue = selectEle.select2('data')[0]['text'];
// Update array
states[cellId] = selectedValue.id;
// Destroy select2
selectEle.select2('destroy');
// Change html to just show the value
cellEle.html(selectedValue.id);
});
}
});
});
})(jQuery)
我的HTML代码如下
<td class="volunteer" id="47">Bob SMith and admin</td>
点击两次
第一次点击单元格会初始化 select2,第二次点击会告诉 select2 显示下拉列表。要只需要单击一次,您可以在初始化 select2 后调用 https://select2.org/programmatic-control/methods 中描述的打开方法。
// Initialise select2
let selectEle = cellEle.children("select").select2();
// Open the select2 dropdown
selectEle.select2('open');
替换Select
当点击值 select2 被销毁时,.html()
调用应将 select 替换为 selected 值,但它不起作用正确,因为 id
属性 在存储值中不存在,这导致单元格恢复为正常 select.
处理 "select2:close"
事件的代码包含 selectedValue = selectEle.select2('data')[0]['text'];
行,它将第一个 selected 值 [0]
的文本放入变量 selectedValue
。在此之后,使用 cellEle.html(selectedValue.id);
更新单元格的 HTML,但此时 selectedValue
仅包含文本(例如“Alabama”),因此没有 .id
属性。要解决此问题,可以将 ID 和文本都存储在数组中,然后在需要的地方使用,例如:
// Store the id and text of all selected values in the array
selectedValue = selectEle.select2('data').map(function(value) {
return { id: value.id, text: value.text };
});
// Get an array of IDs for the selected values (for preselecting values when select2 loads)
selectEle.val(states[cellId].map(function(value) { return value.id })).trigger('change');
// Get a comma separated string of the selected values (for populating the text in the cell)
cellEle.html(states[cellId].map(function(value) { return value.text; }).join(','));
多 Select 模式 -
允许多个 select 离子的示例是 https://jsfiddle.net/aqgbxz1d/ 并且也包含在下面的这个答案中。这似乎是基于问题中 multiple="multiple"
属性 的所需模式。
示例已更新,不再使用 select2:close
事件。相反,它使用 change
事件来存储值更改,并在文档上使用第二个 click
事件处理程序来在用户单击页面上的其他位置时销毁 select2 下拉列表.考虑到您要实现的目标,这似乎是一种更好的方法,因为它使 select 对多个值开放 selected。
单Select模式 - 从评论来看,似乎可能需要单一 select 模式。一个只允许一个 selection 的例子是 https://jsfiddle.net/9jcnwbt2/1/。如果需要单一 select 模式,那么您需要:
- 删除多重属性
multiple="multiple"
- 添加一个空白选项
<option></option>
- 您还可以复制文档点击事件中的代码,该事件会破坏 select2 并将 HTML 更新为更改事件。
(function ($) {
var states = [];
$(document).ready(function () {
$(".volunteer").on("click", function (e) {
// Check if select is already loaded
if (!$(this).has("select").length) {
var cellEle = $(this);
var cellId = this.id;
// Populate select element
cellEle.html(`<select class="js-example-basic" multiple="multiple">
<option value="AL">Alabama</option>
<option value="WY">Wyoming</option>
</select>`);
// Initialise select2
let selectEle = cellEle.children("select").select2({placeholder: "Select a value"});
// Open the select dropdown so user doesn't have to click twice
selectEle.select2('open');
// Check if there is an existing value for this cell
if (states[cellId]) {
// preselect existing value
selectEle.val(states[cellId].map(function (value) {
return value.id
})).trigger('change');
}
// Attach event handler to store value changes
selectEle.on('change', function (e) {
// Get selected values
selectedValues = $(this).select2('data');
// Update the states array with id and text of selected
// values. The id is needed to restore the values if select2
// is reloaded on this cell. The text is required to generate
// the replacement text shown in the cell
states[cellId] = selectedValues.map(function (value) {
return {
id: value.id,
text: value.text
};
});
});
}
// Don't propagate the event
// This prevents this document click handler from executing which would
// remove select2 by calling destroy
e.stopPropagation();
});
});
// Attach event handler to document to capture any clicks
// This will be triggered for all clicks on the page, except those
// captured by the method described above this prevents this firing
// with e.stopPropagation()
// Which this is called select2 on any cells must be destoryed and their
// text value populated
$(document).on('click', function (e) {
// Loop through all select2 elements
$('.js-example-basic').each(function (idx) {
// Get the ID of the cell that's been selected
let cellId = $(this).parent().attr('id');
// Destroy select2 on this element
$(this).select2('destroy');
// Change html on the parent element (td) to just show the value
if(states[cellId] && states[cellId].length > 0){
$(this).parent().html(states[cellId].map(function (value) {
return value.text;
}).join(','));
} else {
$(this).parent().html("Select a value...")
}
});
});
})(jQuery)
.js-example-basic {
width: 200px;
}
thead{
font-weight: bold;
}
table, th, td {
border: 1px solid black;
}
tr {
height: 36px;
}
td {
width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
<table>
<thead>
<tr>
<td>Table Header 1</td>
<td>Table Header 2</td>
</tr>
</thead>
<tbody>
<tr>
<td class="volunteer" id="47">Select a value...</td>
<td class=""></td>
</tr>
<tr>
<td class="volunteer" id="48">Select a value...</td>
<td class=""></td>
</tr>
</tbody>
</table>