How can I deal with tom-select and django form?
I found recently tom-select as alternative to Select2 for my forms. It's a great solution who work perfectly !
It works great when I use to create data from a form but when I want to use to edit data it's another problem.
My edition form is in a modal ad this modal is opened by clicking on edit button on an item listing on main page behind.
I use fetch in javascript to get data and to populate my input/select. It works well when I first open my modal ... but if I click on another item to edit next ... no clear data ... and error message in console saying there is allready an instance of tom-select for this input.
My goal is to retrieve data (sometime it's a single select, sometime it's a multiple select) on tom-select with an easy part as I did with Select2.
Here is my form
<div class="modal fade">[...]
<form id="product-form" method="post" action="{% url 'products' %}" class="mt-2">
{% csrf_token %}
{% include 'form.html' with form=form %}
<input type="hidden" name="id_product" id="id_product" value="" />
<div class="d-flex gap-2">
<a href="#" type="button" class="btn btn-secondary col-3" data-bs-dismiss="modal">{% trans 'Retour' %}</a>
<button id="btn-product-modal" type="submit" class="btn btn-success col-9">{% trans 'Créer' %}</button>
</div>
</form>
</div>
Beginning of my EditModal function
function openModalEdit(pk) {
document.getElementById("product-form").reset();
// Fetch object data using AJAX
fetch(`/product/get_product/${pk}`)
.then(response => response.json())
.then(data => {
// Populate modal fields with fetched data
for (var i = 1; i <= data.entries; i++) {
document.getElementById('id_entry_' + i).value = data['entry_' + i];
var selectElement = document.getElementById('id_entry_' + i);
var selectedValues = data['entry_' + i];
console.log(selectedValues);
if (selectElement.selectize) {
selectElement.selectize.destroy();
}
var tomSelect = new TomSelect(selectElement, {
items: selectedValues
});
}
document.getElementById('id_description').value = data.description;
document.getElementById('id_price').value = data.price;
[...]
In django here is my forms.py
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for category in categories:
entry_choices = Entry.objects.filter(category=category).values_list('id', 'name')
field_name = f'entry_{category.id}'
new_fields[field_name] = forms.ChoiceField(
choices=entry_choices,
widget=forms.Select(attrs={'class': 'select2 form-control', 'placeholder': _(u'Choisissez votre ') + str(category.name)}),
label=category.name
)
self.fields = new_fields
and my views.py calling forms
if pk:
obj = get_object_or_404(Product, pk=pk)
message = _("Produit édité avec succès !")
else:
obj = None
message = _("Produit créé avec succès !")
form = ProductEntryForm(instance=obj)
As you can see I try with destroy() but it doesn't work.
I saw something with sync() , cleaCache() ... etc but don't know how to use them
The objective is to finally find a solution which works with django.
I think I'm close to find a solution but I've some difficult since a while :(