I am trying to save multiple forms via inlineformset_factory but it is not saving any data. And the formset is also returning other fields, like the ID field. inlineformfactories are also returning other foreignkey fields. As for the id field, is it a special form field or a django model field?
forms.py
<code>class ImageFieldForm(forms.ModelForm):
class Meta:
model = ImageField
fields = ('image',)
class VideoFieldForm(forms.ModelForm):
class Meta:
model = VideoField
fields = ('video',)
class AdditionalFieldForm(forms.ModelForm):
class Meta:
model = AdditionalField
fields = ('icon', 'title', 'description',)
ImageFieldFormset = inlineformset_factory(Auction, ImageField, form=ImageFieldForm, extra=0, fields=('image',))
VideoFieldFormset = inlineformset_factory(Auction, VideoField, form=VideoFieldForm, extra=0, fields=('video',))
AdditionalFieldFormset = inlineformset_factory(Auction, AdditionalField, form=AdditionalFieldForm, extra=0, fields=('icon', 'title', 'description',), exclude=('id',))
</code>
<code>class ImageFieldForm(forms.ModelForm):
class Meta:
model = ImageField
fields = ('image',)
class VideoFieldForm(forms.ModelForm):
class Meta:
model = VideoField
fields = ('video',)
class AdditionalFieldForm(forms.ModelForm):
class Meta:
model = AdditionalField
fields = ('icon', 'title', 'description',)
ImageFieldFormset = inlineformset_factory(Auction, ImageField, form=ImageFieldForm, extra=0, fields=('image',))
VideoFieldFormset = inlineformset_factory(Auction, VideoField, form=VideoFieldForm, extra=0, fields=('video',))
AdditionalFieldFormset = inlineformset_factory(Auction, AdditionalField, form=AdditionalFieldForm, extra=0, fields=('icon', 'title', 'description',), exclude=('id',))
</code>
class ImageFieldForm(forms.ModelForm):
class Meta:
model = ImageField
fields = ('image',)
class VideoFieldForm(forms.ModelForm):
class Meta:
model = VideoField
fields = ('video',)
class AdditionalFieldForm(forms.ModelForm):
class Meta:
model = AdditionalField
fields = ('icon', 'title', 'description',)
ImageFieldFormset = inlineformset_factory(Auction, ImageField, form=ImageFieldForm, extra=0, fields=('image',))
VideoFieldFormset = inlineformset_factory(Auction, VideoField, form=VideoFieldForm, extra=0, fields=('video',))
AdditionalFieldFormset = inlineformset_factory(Auction, AdditionalField, form=AdditionalFieldForm, extra=0, fields=('icon', 'title', 'description',), exclude=('id',))
views.py
<code>def auction_create(request):
auction_form = AuctionForm()
image_formset = ImageFieldFormset()
video_formset = VideoFieldFormset()
additional_formset = AdditionalFieldFormset()
if request.method == 'POST':
auction_form = AuctionForm(request.POST, request.FILES)
image_formset = ImageFieldFormset(request.POST, request.FILES)
video_formset = VideoFieldFormset(request.POST, request.FILES)
additional_formset = AdditionalFieldFormset(request.POST, request.FILES)
if all([auction_form.is_valid(), image_formset.is_valid(), video_formset.is_valid(), additional_formset.is_valid()]):
new_auction = auction_form.save(commit=False)
new_auction.owner = request.user
new_auction.save()
new_auction.permissions.add(request.user)
user_permission = AuctionUserPermission.objects.get(user=request.user, auction=new_auction)
user_permission.can_edit = True
user_permission.can_delete = True
user_permission.can_add_admin = True
user_permission.save()
for image_form in image_formset:
new_image_form = image_form.save(commit=False)
new_image_form.auction = new_auction
new_image_form.save()
for video_form in video_formset:
new_video_form = video_form.save(commit=False)
new_video_form.auction = new_auction
new_video_form.save()
for additional_form in additional_formset:
new_additional_form = additional_form.save(commit=False)
new_additional_form.auction = new_auction
new_additional_form.save()
if new_auction.start_time:
pass
if new_auction.end_time:
pass
return redirect('auction', new_auction.slug)
else:
print(image_formset.errors)
context = {
'auction_form': auction_form,
'image_formset': image_formset,
'video_formset': video_formset,
'additional_formset': additional_formset,
}
return render(request, 'auctions/auction-create-update.html', context)
</code>
<code>def auction_create(request):
auction_form = AuctionForm()
image_formset = ImageFieldFormset()
video_formset = VideoFieldFormset()
additional_formset = AdditionalFieldFormset()
if request.method == 'POST':
auction_form = AuctionForm(request.POST, request.FILES)
image_formset = ImageFieldFormset(request.POST, request.FILES)
video_formset = VideoFieldFormset(request.POST, request.FILES)
additional_formset = AdditionalFieldFormset(request.POST, request.FILES)
if all([auction_form.is_valid(), image_formset.is_valid(), video_formset.is_valid(), additional_formset.is_valid()]):
new_auction = auction_form.save(commit=False)
new_auction.owner = request.user
new_auction.save()
new_auction.permissions.add(request.user)
user_permission = AuctionUserPermission.objects.get(user=request.user, auction=new_auction)
user_permission.can_edit = True
user_permission.can_delete = True
user_permission.can_add_admin = True
user_permission.save()
for image_form in image_formset:
new_image_form = image_form.save(commit=False)
new_image_form.auction = new_auction
new_image_form.save()
for video_form in video_formset:
new_video_form = video_form.save(commit=False)
new_video_form.auction = new_auction
new_video_form.save()
for additional_form in additional_formset:
new_additional_form = additional_form.save(commit=False)
new_additional_form.auction = new_auction
new_additional_form.save()
if new_auction.start_time:
pass
if new_auction.end_time:
pass
return redirect('auction', new_auction.slug)
else:
print(image_formset.errors)
context = {
'auction_form': auction_form,
'image_formset': image_formset,
'video_formset': video_formset,
'additional_formset': additional_formset,
}
return render(request, 'auctions/auction-create-update.html', context)
</code>
def auction_create(request):
auction_form = AuctionForm()
image_formset = ImageFieldFormset()
video_formset = VideoFieldFormset()
additional_formset = AdditionalFieldFormset()
if request.method == 'POST':
auction_form = AuctionForm(request.POST, request.FILES)
image_formset = ImageFieldFormset(request.POST, request.FILES)
video_formset = VideoFieldFormset(request.POST, request.FILES)
additional_formset = AdditionalFieldFormset(request.POST, request.FILES)
if all([auction_form.is_valid(), image_formset.is_valid(), video_formset.is_valid(), additional_formset.is_valid()]):
new_auction = auction_form.save(commit=False)
new_auction.owner = request.user
new_auction.save()
new_auction.permissions.add(request.user)
user_permission = AuctionUserPermission.objects.get(user=request.user, auction=new_auction)
user_permission.can_edit = True
user_permission.can_delete = True
user_permission.can_add_admin = True
user_permission.save()
for image_form in image_formset:
new_image_form = image_form.save(commit=False)
new_image_form.auction = new_auction
new_image_form.save()
for video_form in video_formset:
new_video_form = video_form.save(commit=False)
new_video_form.auction = new_auction
new_video_form.save()
for additional_form in additional_formset:
new_additional_form = additional_form.save(commit=False)
new_additional_form.auction = new_auction
new_additional_form.save()
if new_auction.start_time:
pass
if new_auction.end_time:
pass
return redirect('auction', new_auction.slug)
else:
print(image_formset.errors)
context = {
'auction_form': auction_form,
'image_formset': image_formset,
'video_formset': video_formset,
'additional_formset': additional_formset,
}
return render(request, 'auctions/auction-create-update.html', context)
html form
<code>{% extends 'base.html' %}
{% load static %}
{% block title %}{% endblock title %}
{% block header %}
{{ auction_form.media }}
{% endblock header %}
{% block content %}
<!-- Auction Create Section -->
<section class="auction-create">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<h2 class="form-header">Create Auction</h2>
<ul class="tab-headers">
<li class="active" data-content-id="1">Auction Form</li>
<li data-content-id="2">Image Fields</li>
<li data-content-id="3">Video Fields</li>
<li data-content-id="4">Additional Fields</li>
</ul>
<div class="form-body">
<div class="tab-content active" id="1">
{% for field in auction_form %}
<div class="form-control">
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
<button type="submit" class="btn">Save</button>
</div>
<div class="tab-content" id="2">
{{ image_formset.management_form }}
<div class="additional-fields">
{% for image_form in image_formset %}
<div class="additional-image-field">
{% for field in image_form %}
<div class="form-control">
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
{% comment %} <div class="form-control delete-checkbox">
{{ image_form.DELETE.label_tag }}
{{ image_form.DELETE }}
{{ image_form.DELETE.errors }}
</div> {% endcomment %}
</div>
{% endfor %}
</div>
<button type="button" class='btn' id="add-image-field">+ Add Another Field</button>
<!-- hidden form -->
<div id="empty-image-form" class="hidden">
<div class="form-control">
{{ image_formset.empty_form.image.label_tag }}
{{ image_formset.empty_form.image }}
{{ image_formset.empty_form.image.errors }}
</div>
<button type="button" class="btn btn-image-remove">Remove</button>
</div>
</div>
<div class="tab-content" id="3">
{{ video_formset.management_form }}
<div class="additional-fields">
{% for video_form in video_formset %}
<div class="additional-video-field">
<div class="form-control">
{{ video_form.video.label_tag }}
{{ video_form.video }}
{{ video_form.video.errors }}
</div>
<div class="form-control delete-checkbox">
{{ video_form.DELETE.label_tag }}
{{ video_form.DELETE }}
{{ video_form.DELETE.errors }}
</div>
</div>
{% endfor %}
</div>
<button type="button" class='btn' id="add-video-field">+ Add Another Field</button>
<!-- hidden form -->
<div id="empty-video-form" class="hidden">
<div class="form-control">
{{ video_formset.empty_form.video.label_tag }}
{{ video_formset.empty_form.video }}
{{ video_formset.empty_form.video.errors }}
</div>
<button type="button" class="btn btn-video-remove">Remove</button>
</div>
</div>
<div class="tab-content" id="4">
{{ additional_formset.management_form }}
<div class="additional-fields">
{% for additional_form in additional_formset %}
<div class="additional-additional-field">
{% for field in additional_form %}
<div class="form-control">
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
<button type="button" class='btn' id="add-additional-field">+ Add Another Field</button>
</div>
<!-- hidden form -->
<div id="empty-additional-form" class="hidden">
{% for form in additional_formset.empty_form %}
<div class="form-control">
{{ form.label_tag }}
{{ form }}
{{ form.errors }}
</div>
{% endfor %}
<button type="button" class="btn btn-additional-remove">Remove</button>
</div>
</div>
</form>
</section>
<!-- Auction Create Section end -->
{% endblock content %}
{% block script %}
<script src="{% static 'js/tabs.js' %}"></script>
<script>
function setupFormsetHandlers(formsetPrefix, addButtonId, additionalFieldsIndex) {
const AddFieldButton = document.querySelector(`#${addButtonId}`);
const AdditionalFields = document.querySelectorAll('.additional-fields')[additionalFieldsIndex];
const emptyFormTemplate = document.querySelector(`#empty-${formsetPrefix}-form`);
const regex = new RegExp('__prefix__', 'g');
AddFieldButton.addEventListener('click', () => {
const AdditionalFieldsCount = document.querySelectorAll(`.additional-${formsetPrefix}-field`).length;
const emptyForm = emptyFormTemplate.cloneNode(true);
emptyForm.setAttribute('class', `additional-${formsetPrefix}-field`);
emptyForm.setAttribute('id', '');
emptyForm.innerHTML = emptyForm.innerHTML.replace(regex, AdditionalFieldsCount);
AdditionalFields.append(emptyForm);
// Update TOTAL_FORMS count
const totalFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-TOTAL_FORMS]`);
const initialFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-INITIAL_FORMS]`);
totalFormsInput.value = AdditionalFieldsCount + 1;
initialFormsInput.value = AdditionalFieldsCount + 1;
removeFieldHandlers(formsetPrefix, AdditionalFields);
});
}
function removeFieldHandlers(formsetPrefix, AdditionalFields) {
const allAdditionalFieldBtns = AdditionalFields.querySelectorAll(`.btn-${formsetPrefix}-remove`);
allAdditionalFieldBtns.forEach(btn => {
btn.addEventListener('click', () => {
const field = btn.parentElement;
AdditionalFields.removeChild(field);
// Adjust indexes after removing
const forms = AdditionalFields.querySelectorAll(`.additional-${formsetPrefix}-field`);
forms.forEach((form, index) => {
const regexAfterRemove = new RegExp(`${index + 1}`, 'g');
form.innerHTML = form.innerHTML.replace(regexAfterRemove, index);
});
// Update TOTAL_FORMS count
const totalFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-TOTAL_FORMS]`);
const initialFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-INITIAL_FORMS]`);
totalFormsInput.value = forms.length;
initialFormsInput.value = forms.length;
removeFieldHandlers(formsetPrefix, AdditionalFields);
});
});
}
// Setup handlers for each formset
setupFormsetHandlers('image', 'add-image-field', 0);
setupFormsetHandlers('video', 'add-video-field', 1);
setupFormsetHandlers('additional', 'add-additional-field', 2);
function updateFormsetManagementForms(formsetPrefix) {
const AdditionalFields = document.querySelectorAll('.additional-fields')[additionalFieldsIndex];
const totalFormsInput = document.querySelector(`.input[name=${formsetPrefix}-TOTAL_FORMS]`);
const initialFormsInput = document.querySelector(`.input[name=${formsetPrefix}-INITIAL_FORMS]`);
totalFormsInput = AdditionalFields.childElementCount;
initialFormsInput.value = forms.length; // Adjust this if initial forms count is different
// Update any hidden form templates for adding new forms
const emptyFormTemplate = document.querySelector(`#empty-${formsetPrefix}-form`);
const newFormIndex = forms.length; // Use this index to adjust the template for the next form
emptyFormTemplate.innerHTML = emptyFormTemplate.innerHTML.replace(/prefix/g, newFormIndex);
};
</script>
{% endblock script %}
</code>
<code>{% extends 'base.html' %}
{% load static %}
{% block title %}{% endblock title %}
{% block header %}
{{ auction_form.media }}
{% endblock header %}
{% block content %}
<!-- Auction Create Section -->
<section class="auction-create">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<h2 class="form-header">Create Auction</h2>
<ul class="tab-headers">
<li class="active" data-content-id="1">Auction Form</li>
<li data-content-id="2">Image Fields</li>
<li data-content-id="3">Video Fields</li>
<li data-content-id="4">Additional Fields</li>
</ul>
<div class="form-body">
<div class="tab-content active" id="1">
{% for field in auction_form %}
<div class="form-control">
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
<button type="submit" class="btn">Save</button>
</div>
<div class="tab-content" id="2">
{{ image_formset.management_form }}
<div class="additional-fields">
{% for image_form in image_formset %}
<div class="additional-image-field">
{% for field in image_form %}
<div class="form-control">
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
{% comment %} <div class="form-control delete-checkbox">
{{ image_form.DELETE.label_tag }}
{{ image_form.DELETE }}
{{ image_form.DELETE.errors }}
</div> {% endcomment %}
</div>
{% endfor %}
</div>
<button type="button" class='btn' id="add-image-field">+ Add Another Field</button>
<!-- hidden form -->
<div id="empty-image-form" class="hidden">
<div class="form-control">
{{ image_formset.empty_form.image.label_tag }}
{{ image_formset.empty_form.image }}
{{ image_formset.empty_form.image.errors }}
</div>
<button type="button" class="btn btn-image-remove">Remove</button>
</div>
</div>
<div class="tab-content" id="3">
{{ video_formset.management_form }}
<div class="additional-fields">
{% for video_form in video_formset %}
<div class="additional-video-field">
<div class="form-control">
{{ video_form.video.label_tag }}
{{ video_form.video }}
{{ video_form.video.errors }}
</div>
<div class="form-control delete-checkbox">
{{ video_form.DELETE.label_tag }}
{{ video_form.DELETE }}
{{ video_form.DELETE.errors }}
</div>
</div>
{% endfor %}
</div>
<button type="button" class='btn' id="add-video-field">+ Add Another Field</button>
<!-- hidden form -->
<div id="empty-video-form" class="hidden">
<div class="form-control">
{{ video_formset.empty_form.video.label_tag }}
{{ video_formset.empty_form.video }}
{{ video_formset.empty_form.video.errors }}
</div>
<button type="button" class="btn btn-video-remove">Remove</button>
</div>
</div>
<div class="tab-content" id="4">
{{ additional_formset.management_form }}
<div class="additional-fields">
{% for additional_form in additional_formset %}
<div class="additional-additional-field">
{% for field in additional_form %}
<div class="form-control">
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
<button type="button" class='btn' id="add-additional-field">+ Add Another Field</button>
</div>
<!-- hidden form -->
<div id="empty-additional-form" class="hidden">
{% for form in additional_formset.empty_form %}
<div class="form-control">
{{ form.label_tag }}
{{ form }}
{{ form.errors }}
</div>
{% endfor %}
<button type="button" class="btn btn-additional-remove">Remove</button>
</div>
</div>
</form>
</section>
<!-- Auction Create Section end -->
{% endblock content %}
{% block script %}
<script src="{% static 'js/tabs.js' %}"></script>
<script>
function setupFormsetHandlers(formsetPrefix, addButtonId, additionalFieldsIndex) {
const AddFieldButton = document.querySelector(`#${addButtonId}`);
const AdditionalFields = document.querySelectorAll('.additional-fields')[additionalFieldsIndex];
const emptyFormTemplate = document.querySelector(`#empty-${formsetPrefix}-form`);
const regex = new RegExp('__prefix__', 'g');
AddFieldButton.addEventListener('click', () => {
const AdditionalFieldsCount = document.querySelectorAll(`.additional-${formsetPrefix}-field`).length;
const emptyForm = emptyFormTemplate.cloneNode(true);
emptyForm.setAttribute('class', `additional-${formsetPrefix}-field`);
emptyForm.setAttribute('id', '');
emptyForm.innerHTML = emptyForm.innerHTML.replace(regex, AdditionalFieldsCount);
AdditionalFields.append(emptyForm);
// Update TOTAL_FORMS count
const totalFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-TOTAL_FORMS]`);
const initialFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-INITIAL_FORMS]`);
totalFormsInput.value = AdditionalFieldsCount + 1;
initialFormsInput.value = AdditionalFieldsCount + 1;
removeFieldHandlers(formsetPrefix, AdditionalFields);
});
}
function removeFieldHandlers(formsetPrefix, AdditionalFields) {
const allAdditionalFieldBtns = AdditionalFields.querySelectorAll(`.btn-${formsetPrefix}-remove`);
allAdditionalFieldBtns.forEach(btn => {
btn.addEventListener('click', () => {
const field = btn.parentElement;
AdditionalFields.removeChild(field);
// Adjust indexes after removing
const forms = AdditionalFields.querySelectorAll(`.additional-${formsetPrefix}-field`);
forms.forEach((form, index) => {
const regexAfterRemove = new RegExp(`${index + 1}`, 'g');
form.innerHTML = form.innerHTML.replace(regexAfterRemove, index);
});
// Update TOTAL_FORMS count
const totalFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-TOTAL_FORMS]`);
const initialFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-INITIAL_FORMS]`);
totalFormsInput.value = forms.length;
initialFormsInput.value = forms.length;
removeFieldHandlers(formsetPrefix, AdditionalFields);
});
});
}
// Setup handlers for each formset
setupFormsetHandlers('image', 'add-image-field', 0);
setupFormsetHandlers('video', 'add-video-field', 1);
setupFormsetHandlers('additional', 'add-additional-field', 2);
function updateFormsetManagementForms(formsetPrefix) {
const AdditionalFields = document.querySelectorAll('.additional-fields')[additionalFieldsIndex];
const totalFormsInput = document.querySelector(`.input[name=${formsetPrefix}-TOTAL_FORMS]`);
const initialFormsInput = document.querySelector(`.input[name=${formsetPrefix}-INITIAL_FORMS]`);
totalFormsInput = AdditionalFields.childElementCount;
initialFormsInput.value = forms.length; // Adjust this if initial forms count is different
// Update any hidden form templates for adding new forms
const emptyFormTemplate = document.querySelector(`#empty-${formsetPrefix}-form`);
const newFormIndex = forms.length; // Use this index to adjust the template for the next form
emptyFormTemplate.innerHTML = emptyFormTemplate.innerHTML.replace(/prefix/g, newFormIndex);
};
</script>
{% endblock script %}
</code>
{% extends 'base.html' %}
{% load static %}
{% block title %}{% endblock title %}
{% block header %}
{{ auction_form.media }}
{% endblock header %}
{% block content %}
<!-- Auction Create Section -->
<section class="auction-create">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<h2 class="form-header">Create Auction</h2>
<ul class="tab-headers">
<li class="active" data-content-id="1">Auction Form</li>
<li data-content-id="2">Image Fields</li>
<li data-content-id="3">Video Fields</li>
<li data-content-id="4">Additional Fields</li>
</ul>
<div class="form-body">
<div class="tab-content active" id="1">
{% for field in auction_form %}
<div class="form-control">
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
<button type="submit" class="btn">Save</button>
</div>
<div class="tab-content" id="2">
{{ image_formset.management_form }}
<div class="additional-fields">
{% for image_form in image_formset %}
<div class="additional-image-field">
{% for field in image_form %}
<div class="form-control">
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
{% comment %} <div class="form-control delete-checkbox">
{{ image_form.DELETE.label_tag }}
{{ image_form.DELETE }}
{{ image_form.DELETE.errors }}
</div> {% endcomment %}
</div>
{% endfor %}
</div>
<button type="button" class='btn' id="add-image-field">+ Add Another Field</button>
<!-- hidden form -->
<div id="empty-image-form" class="hidden">
<div class="form-control">
{{ image_formset.empty_form.image.label_tag }}
{{ image_formset.empty_form.image }}
{{ image_formset.empty_form.image.errors }}
</div>
<button type="button" class="btn btn-image-remove">Remove</button>
</div>
</div>
<div class="tab-content" id="3">
{{ video_formset.management_form }}
<div class="additional-fields">
{% for video_form in video_formset %}
<div class="additional-video-field">
<div class="form-control">
{{ video_form.video.label_tag }}
{{ video_form.video }}
{{ video_form.video.errors }}
</div>
<div class="form-control delete-checkbox">
{{ video_form.DELETE.label_tag }}
{{ video_form.DELETE }}
{{ video_form.DELETE.errors }}
</div>
</div>
{% endfor %}
</div>
<button type="button" class='btn' id="add-video-field">+ Add Another Field</button>
<!-- hidden form -->
<div id="empty-video-form" class="hidden">
<div class="form-control">
{{ video_formset.empty_form.video.label_tag }}
{{ video_formset.empty_form.video }}
{{ video_formset.empty_form.video.errors }}
</div>
<button type="button" class="btn btn-video-remove">Remove</button>
</div>
</div>
<div class="tab-content" id="4">
{{ additional_formset.management_form }}
<div class="additional-fields">
{% for additional_form in additional_formset %}
<div class="additional-additional-field">
{% for field in additional_form %}
<div class="form-control">
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
<button type="button" class='btn' id="add-additional-field">+ Add Another Field</button>
</div>
<!-- hidden form -->
<div id="empty-additional-form" class="hidden">
{% for form in additional_formset.empty_form %}
<div class="form-control">
{{ form.label_tag }}
{{ form }}
{{ form.errors }}
</div>
{% endfor %}
<button type="button" class="btn btn-additional-remove">Remove</button>
</div>
</div>
</form>
</section>
<!-- Auction Create Section end -->
{% endblock content %}
{% block script %}
<script src="{% static 'js/tabs.js' %}"></script>
<script>
function setupFormsetHandlers(formsetPrefix, addButtonId, additionalFieldsIndex) {
const AddFieldButton = document.querySelector(`#${addButtonId}`);
const AdditionalFields = document.querySelectorAll('.additional-fields')[additionalFieldsIndex];
const emptyFormTemplate = document.querySelector(`#empty-${formsetPrefix}-form`);
const regex = new RegExp('__prefix__', 'g');
AddFieldButton.addEventListener('click', () => {
const AdditionalFieldsCount = document.querySelectorAll(`.additional-${formsetPrefix}-field`).length;
const emptyForm = emptyFormTemplate.cloneNode(true);
emptyForm.setAttribute('class', `additional-${formsetPrefix}-field`);
emptyForm.setAttribute('id', '');
emptyForm.innerHTML = emptyForm.innerHTML.replace(regex, AdditionalFieldsCount);
AdditionalFields.append(emptyForm);
// Update TOTAL_FORMS count
const totalFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-TOTAL_FORMS]`);
const initialFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-INITIAL_FORMS]`);
totalFormsInput.value = AdditionalFieldsCount + 1;
initialFormsInput.value = AdditionalFieldsCount + 1;
removeFieldHandlers(formsetPrefix, AdditionalFields);
});
}
function removeFieldHandlers(formsetPrefix, AdditionalFields) {
const allAdditionalFieldBtns = AdditionalFields.querySelectorAll(`.btn-${formsetPrefix}-remove`);
allAdditionalFieldBtns.forEach(btn => {
btn.addEventListener('click', () => {
const field = btn.parentElement;
AdditionalFields.removeChild(field);
// Adjust indexes after removing
const forms = AdditionalFields.querySelectorAll(`.additional-${formsetPrefix}-field`);
forms.forEach((form, index) => {
const regexAfterRemove = new RegExp(`${index + 1}`, 'g');
form.innerHTML = form.innerHTML.replace(regexAfterRemove, index);
});
// Update TOTAL_FORMS count
const totalFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-TOTAL_FORMS]`);
const initialFormsInput = document.querySelector(`input[name=${formsetPrefix}_fields-INITIAL_FORMS]`);
totalFormsInput.value = forms.length;
initialFormsInput.value = forms.length;
removeFieldHandlers(formsetPrefix, AdditionalFields);
});
});
}
// Setup handlers for each formset
setupFormsetHandlers('image', 'add-image-field', 0);
setupFormsetHandlers('video', 'add-video-field', 1);
setupFormsetHandlers('additional', 'add-additional-field', 2);
function updateFormsetManagementForms(formsetPrefix) {
const AdditionalFields = document.querySelectorAll('.additional-fields')[additionalFieldsIndex];
const totalFormsInput = document.querySelector(`.input[name=${formsetPrefix}-TOTAL_FORMS]`);
const initialFormsInput = document.querySelector(`.input[name=${formsetPrefix}-INITIAL_FORMS]`);
totalFormsInput = AdditionalFields.childElementCount;
initialFormsInput.value = forms.length; // Adjust this if initial forms count is different
// Update any hidden form templates for adding new forms
const emptyFormTemplate = document.querySelector(`#empty-${formsetPrefix}-form`);
const newFormIndex = forms.length; // Use this index to adjust the template for the next form
emptyFormTemplate.innerHTML = emptyFormTemplate.innerHTML.replace(/prefix/g, newFormIndex);
};
</script>
{% endblock script %}
New contributor
Minecraft PC is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.