Динамическое добавление/удаление набора форм Django Не работает для цветов, размеров и изображений

Постановка задачи

Я работаю над набором форм Django, где пользователи могут динамически добавлять/ удалять цвета, размеры и изображения при добавлении товара.

Структура моего набора форм выглядит следующим образом:

  • Продукт может иметь несколько цветов.
  • Каждый цвет может иметь несколько размеров.
  • Каждый цвет может содержать несколько изображений.
  • Пользователи должны иметь возможность динамически добавлять/удалять цвета, размеры и изображения с помощью JavaScript.

Ожидаемое поведение

  1. При нажатии кнопки "Add Color" должна быть создана новая цветовая форма со своим собственным размером и разделами изображений.
  2. Нажатие "Add Size" в пределах цвета должно добавить новый размер только к этому конкретному цвету.
  3. Нажатие "Add Image" в пределах цвета должно добавить новое изображение только к этому конкретному цвету.
  4. Нажатие кнопки "Remove Color" должно удалить раздел с определенным цветом.

Текущая проблема

  • Работает только кнопка "Удалить цвет".
  • "Add Color", "Add Size", и кнопки "Add Image" не работают.
  • При нажатии кнопок к DOM не добавляются новые элементы.

Попытки отладки

✔ Проверил Формы управления набором форм Django (они существуют).
✔ Проверенные прослушиватели событий подключаются с помощью console.log().
✔ Гарантируется, что cloneNode(true) правильно копирует элементы.
✔ Проверено на наличие ошибок JavaScript в консоли (синтаксических ошибок нет).

<время работы/>

Формы и наборы форм Django

Формы (forms.py)

from django import forms
from django.forms import inlineformset_factory
from .models import VendorProduct, ProductColor, ProductSize, ProductImage, ColorImage

class ProductForm(forms.ModelForm):
    class Meta:
        model = VendorProduct
        fields = ['title', 'category', 'base_price']
        widgets = {
            'title': forms.TextInput(attrs={'class': 'form-control'}),
            'category': forms.Select(attrs={'class': 'form-control'}),
            'base_price': forms.NumberInput(attrs={'class': 'form-control'}),
        }

class ProductColorForm(forms.ModelForm):
    class Meta:
        model = ProductColor
        fields = ['color_name', 'color_code']
        widgets = {
            'color_name': forms.TextInput(attrs={'class': 'form-control'}),
            'color_code': forms.TextInput(attrs={'class': 'form-control'}),
        }

class ProductSizeForm(forms.ModelForm):
    class Meta:
        model = ProductSize
        fields = ['size_name', 'stock', 'price_increment']
        widgets = {
            'size_name': forms.TextInput(attrs={'class': 'form-control'}),
            'stock': forms.NumberInput(attrs={'class': 'form-control'}),
            'price_increment': forms.NumberInput(attrs={'class': 'form-control'}),
        }

class ProductImageForm(forms.ModelForm):
    class Meta:
        model = ProductImage
        fields = ['image']
        widgets = {
            'image': forms.FileInput(attrs={'class': 'form-control'}),
        }

class ColorImageForm(forms.ModelForm):
    class Meta:
        model = ColorImage
        fields = ['image']
        widgets = {
            'image': forms.FileInput(attrs={'class': 'form-control'}),
        }

# Formsets
ProductColorFormSet = inlineformset_factory(VendorProduct, ProductColor, form=ProductColorForm, extra=1, can_delete=True)
ProductImageFormSet = inlineformset_factory(VendorProduct, ProductImage, form=ProductImageForm, extra=1, can_delete=True)
ProductSizeFormSet = inlineformset_factory(ProductColor, ProductSize, form=ProductSizeForm, extra=1, can_delete=True)
ColorImageFormSet = inlineformset_factory(ProductColor, ColorImage, form=ColorImageForm, extra=1, can_delete=True)
<время работы/>

HTML-шаблон (add_product.html)

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}

    <div id="colorContainer">
        {% for color_form in color_formset %}
            <div class="color-item">
                {{ color_form.color_name.label_tag }}
                {{ color_form.color_name }}

                {{ color_form.color_code.label_tag }}
                {{ color_form.color_code }}

                <!-- Image Uploads -->
                <label>Color Images</label>
                {{ color_image_formset.management_form }}
                {% for image_form in color_image_formset %}
                    <div class="image-item">
                        {{ image_form.image }}
                    </div>
                {% endfor %}
                <button type="button" class="add-image-btn">Add Image</button>

                <!-- Size Section -->
                <div class="sizeContainer">
                    <h4>Sizes</h4>
                    {{ size_formset.management_form }}
                    {% for size_form in size_formset %}
                        <div class="size-item">
                            {{ size_form.size_name.label_tag }}
                            {{ size_form.size_name }}

                            {{ size_form.stock.label_tag }}
                            {{ size_form.stock }}

                            {{ size_form.price_increment.label_tag }}
                            {{ size_form.price_increment }}
                        </div>
                    {% endfor %}
                </div>
                
                <button type="button" class="add-size-btn">Add Size</button>
                <button type="button" class="remove-btn">Remove Color</button>
            </div>
        {% endfor %}
    </div>

    <button type="button" id="addColorButton">Add Color</button>
    <button type="submit">Save</button>
</form>
<время работы/>

JavaScript (dynamic.js)

<время работы/>

Краткое изложение проблем

  • Прослушиватели событий не были подключены должным образом.
  • Имена наборов форм динамически не обновлялись.
  • JavaScript неправильно использовал делегирование событий.
  • Скрипт должен был обрабатывать как статические, так и динамически добавляемые элементы.
Вернуться на верх