【问题标题】:Selectize.js: cloning of the element and destroy() issueSelectize.js:元素的克隆和destroy()问题
【发布时间】:2021-09-12 15:30:43
【问题描述】:
我正在使用Selectize.js,我需要使用转换后的选择元素来克隆 html 子表单。
在我克隆并插入子表单后,选择功能被破坏。
我读过一个解决方案是为克隆的选择调用destroy()方法,然后再次为它们初始化选择。
我尝试关注此advice,我的代码如下所示:
$(formFields).find("select").each(function(){
if (this.selectize) {
this.selectize.destroy();
}
});
我希望看到的是标准的选择元素,但我看到的选择的元素不具备下拉功能。有什么想法吗?
【问题讨论】:
标签:
javascript
jquery
selectize.js
【解决方案1】:
selectize 对象被添加到原来的选择/输入元素实例中。确保添加 [0] 来指定选择对象:
$(this)[0].selectize.destroy();
具体例子见Selectize API Docs。
此外,我看到很多关于克隆 selectize.js 元素的未解决问题。以下是我的大致流程:
// Trigger when add row button clicked
$('.row-add').click(function() {
// Find last row in table (or div) to clone from
var lastRow = $("myTable").find('tr').last();
// Determine if selectize.js is in use on any element and disable
// before cloning.
var selectizeElements = {};
lastRow.find('select').each(function() {
if ($(this)[0].selectize) {
// Store last row's current options and value(s) to
// restore after destroying for clone purposes.
selectizeElements[$(this).attr('id')] = {
inputOptions: $(this)[0].selectize.options,
inputValue: $(this)[0].selectize.getValue()
}
// Destroy the selectize.js element
$(this)[0].selectize.destroy();
}
});
// Clone last row
newRow = lastRow.clone().insertAfter(lastRow);
// Clear any data that was already entered in the cloned row
newRow.find( 'input,select,textarea' ).each(function() {
$(this).val( '' );
$(this).attr( 'checked', false );
});
// Re-enable any selectize.js fields if needed, adding back
// any options and selected values to the original row.
if (!$.isEmptyObject(selectizeElements) {
$.each(selectizeElements, function(key, value) {
lastRow.find('select#'+key).selectize();
newRow.find('select#'+key).selectize();
})
// Copy back options and values to cloned row
$.each(selectizeElements, function(key, value) {
lastRow.find('select#'+key)[0].selectize.addOption(value.inputOptions);
lastRow.find('select#'+key)[0].selectize.setValue(value.inputValue);
});
}
// I usually update the id and name attribute index number here so
// that each form element has a unique id and name.
});
您可以在 Repo 中找到一些工作示例代码
【解决方案2】:
// When add button is clicked
$('#add').on('click',function(){
$('.combobox').each(function(){ // do this for every select with the 'combobox' class
if ($(this)[0].selectize) { // requires [0] to select the proper object
var value = $(this).val(); // store the current value of the select/input
$(this)[0].selectize.destroy(); // destroys selectize()
$(this).val(value); // set back the value of the select/input
}
});
$('#monsters .form-group:first')
.clone() // copy
.insertAfter('#monsters .form-group:last'); // where
selectizeme(); // reinitialize selectize on all .combobox
});
尝试访问这里:
http://mariolurig.com/selectize-demo.htm
【解决方案3】:
// i equal to duplcate number
let i = 0;
var original = document.querySelector(".duplcate");
$(document).ready(function() {
$(".selectize-select").selectize({
sortField: "text",
});
});
$("#add-student-btn").click(function() {
// Determine if selectize.js is in use on any element and disable
// before cloning.
var selectizeElements = {};
$(original)
.find("select")
.each(function() {
if ($(this)[0].selectize) {
selectedValue = $(this)[0].selectize.getValue();
selectizeElements[$(this).attr("id")] = {
inputOptions: Object.values($(this)[0].selectize.options),
inputValue: $(this)[0].selectize.getValue(),
};
// Destroy the selectize.js element
$(this)[0].selectize.destroy();
}
});
var clone = original.cloneNode(true); // "deep" clone
i = i + 3;
// original.children[0].removeChild(original.children[0].children[2]);
clone.id = "duplicater" + i; // there can only be one element with an ID
clone.style.display = "block";
clone.children[0].children[1].children[0].id = "relation" + i;
clone.children[0].children[0].children[0].id = i;
this.parentNode.parentNode.insertBefore(clone, this.parentNode);
// Clear any data that was already entered in the cloned row
$(clone)
.find("input,select,textarea")
.each(function() {
$(this).val("");
$(this).attr("checked", false);
});
// Re-enable any selectize.js fields if needed, adding back
// any options and selected values to the original row.
if (!$.isEmptyObject(selectizeElements)) {
$.each(selectizeElements, function(key, value) {
$(original)
.find("select#" + key)
.selectize();
});
$(clone)
.find("select.selectize-select")
.selectize();
// Copy back options and values to cloned row
$.each(selectizeElements, function(key, value) {
//return back options and values to orginal element
$(original).find('select#' + key)[0].selectize.addOption(value.inputOptions);
$(original).find('select#' + key)[0].selectize.setValue(value.inputValue);
//add options to the cloned elements
$(clone).find('select#' + key)[0].selectize.addOption(value.inputOptions);
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" class="flexAlignCenter flexColumn">
<div class="formGroup">
<div class="inputDetails flexAlignStart flexColumn">
<label for="name">Name</label>
<input type="text" id="name" name="name" placeholder="" required>
</div>
<div class="inputDetails flexAlignStart flexColumn">
<label for="phone">Phone</label>
<input type="number" id="phone" name="phone" placeholder=""
max="999999999">
</div>
</div>
<div class="formGroup">
<div class="inputDetails flexAlignStart flexColumn">
<label for="password">password</label>
<input type="password" id="password" name="password"
placeholder="enter password">
</div>
</div>
<div class="formGroup">
<div class="inputDetails flexAlignStart flexColumn">
<label for="name">Address</label>
<input type="text" id="address" name="address" placeholder="Enter address">
</div>
</div>
<div class="formGroup duplcate">
<div class="formGroup">
<div class="inputDetails flexAlignStart flexColumn">
<label for="name">Student</label>
<select name="student[]" class="form-control selectize-select" id="0">
<option>choose Student</option>
<option value='1'>Student1</option>
<option value='2'>Student2</option>
<option value='3'>Student3</option>
<option value='4'>Student4</option>
</select>
</div>
<div class="inputDetails flexAlignStart flexColumn">
<label for="name">RelationShip</label>
<select name="relation[]" class="form-control selectize-select" id="relation0">
<option >choose relationShip</option>
<option value="1">Father</option>
<option value="2">Mother</option>
<option value="3">Sister</option>
</select>
</div>
</div>
</div>
<div class="add-new-dev-type">
<div class="addClass">
<span id="add-student-btn" style="font-size:32px; ">+</span>
<span >Add student</span>
</div>
<input type="submit" value="submit" />
</div>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.13.3/js/standalone/selectize.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.13.3/css/selectize.min.css" rel="stylesheet"/>
如果你有很多改变其他选择选项的 onchange 函数,你应该从你想要复制的元素中制作一个隐藏的副本,并将其添加到可见的元素之前。克隆的将从隐藏的创建。