I'm using Django 4.0 , using the invoice template (<a>https://preview.keenthemes.com/metronic8/demo9/dark/apps/invoices/create.html</a>).
In the add item section i have replaced the text field with a select2 tag with options filled in dynamically by django.
Ex :
<select name="item[]" class="form-select form-select-solid" data-control="select2" data-placeholder="Select an item">
<option></option>
{% for item in items %}
<option value="{{item.id}}">{{item.name}}</option>
{% endfor %}
</select>
Hi, you'll need to re-init the newly created select2 when form repeater adds it in.
Please check our official documentation on this here: https://preview.keenthemes.com/metronic8/demo1/documentation/forms/formrepeater/advanced.html
It may be a JS solution, but the concept is similar. Basically, form repeater duplicates the HTML markup, but it doesn't initialize anything after duplicating. If an element requires initialization on load, then newly duplicated elements will not work. You'll just need to re-init the element every form repeater creates a new duplicate.
Thanks.
Hello , thank you for the prompt and detailed help.
My problem is that i am using the invoice template which does not use repeater. It works on appending item-template to the table as you may know.
I re-init the select2 as wherein item-select is the class common in both selects i.e the static & the newly added one:
form.querySelector("[data-kt-element="items"] [data-kt-element="add-item"]").addEventListener("click", function (e) {
e.preventDefault();
var item = form.querySelector("[data-kt-element="item-template"] tr").cloneNode(true);
form.querySelector("[data-kt-element="items"] tbody").appendChild(item);
$(".item-select").select2()
handleEmptyState();
// updateTotal();
});
Hi Bruce ,
I had the same issue (js Repeater generating 2 select2 dropdown),
The problem is not the js repeater, but the select2 bad rendering machinery,
That's why I moved from select2 to tagify (select option), here : https://yaireo.github.io/tagify/#section-mode-select
hope it gave you some hints.
Sure select2 is more thank great to use, but I didn't fint another alternative except using tagify (select option).
If you find a workarround, let me know, please, I use also Django 4.
Thank you.
Hi, riterix has a good alternative solution. However, if you're still keen to use Select2, then the best way to solve this is by reinitializing the newly duplicated Select2 elements only.
If you reinitalize the Select2 elements that was already initalized, then Select2 "may" create duplicates of itself (yes, Select2 can be weird sometimes).
We have a solution where it will only initialize Select2 elements that haven't been initialized here: https://preview.keenthemes.com/metronic8/demo1/apps/ecommerce/catalog/add-product.html
Here's the code snippet of now we did it:
const initFormRepeater = () => {
$("#kt_ecommerce_add_product_options").repeater({
initEmpty: false,
defaultValues: {
"text-input": "foo"
},
show: function () {
$(this).slideDown();
// Init select2 on new repeated items
initConditionsSelect2();
},
hide: function (deleteElement) {
$(this).slideUp(deleteElement);
}
});
}
// Init condition select2
const initConditionsSelect2 = () => {
// Init new repeating condition types
const allConditionTypes = document.querySelectorAll("[data-kt-ecommerce-catalog-add-product="product_option"]");
allConditionTypes.forEach(type => {
if ($(type).hasClass("select2-hidden-accessible")) {
return;
} else {
$(type).select2({
minimumResultsForSearch: -1
});
}
});
}
Hi Shane,
Thank you sooo much for the code, since I want to use select2 because it offers more freedom to use cusom code with it, specially templates.
In a meanwhile I'm looking to avoid front-end and move the repeater to the Django side by using HTMX (it was created specificaly to take off the JS hasstle with minumum implication).
Thank you.
That's a cool direction to go and the implementation logic should be the same. Unfortunately, we may not fully support your Django questions since we're not fully versed in it, but we'll try our best
Happy coding!
Hi Bruce,
Found your question as I faced the same issue, sorted this out as follows:
var item = form.querySelector("[data-kt-element="item-template"] tr").cloneNode(true);
$(item).find(".name1").select2();
<select class="form-select form-select-solid mb-2 name1" data-placeholder="BTA">