I’m facing an issue where dynamic formsets (for event dates and times) on the frontend are not saving correctly. The form is properly rendered, and new event dates and times are added dynamically using Alpine.js, but when the form is submitted, the data does not persist. This issue does not occur in the Django admin interface, where formsets work fine. I suspect the problem is related to how the formset data is being processed on the frontend. I’m using Django with Alpine.js for formset handling, and I’m looking for help in resolving the issue of saving the dynamic formset data on the frontend.
this my models.py
from django.db import models
from django.forms import ValidationError
from django.urls import reverse
from autoslug import AutoSlugField
from django_countries.fields import CountryField
from django.core.validators import RegexValidator
from django.utils.translation import gettext as _
from birthday import BirthdayField, BirthdayManager
class EventOption(models.Model):
name = models.CharField(_("Option name"), max_length=100)
amount = models.DecimalField(_("Price"), max_digits=10, decimal_places=2)
slug = AutoSlugField(populate_from='name', unique=True)
published = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = _("Event Option")
verbose_name_plural = _("Event Options")
def __str__(self):
return self.name
class Event(models.Model):
name = models.CharField(_("Event name"), max_length=100)
slug = AutoSlugField(populate_from='name', unique=True)
published = models.DateTimeField(auto_now_add=True)
options = models.ManyToManyField(EventOption, verbose_name=_("Event Options"), blank=True)
amount = models.DecimalField(_("Price"), max_digits=10, decimal_places=2)
description = models.TextField(_("Description"), blank=True, null=True)
class Meta:
verbose_name = _("Event")
verbose_name_plural = _("Events")
def __str__(self):
return self.name
class EventDate(models.Model):
event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='event_dates')
date = models.DateField(_("Event date"))
class Meta:
verbose_name = _("Event Date")
verbose_name_plural = _("Event Dates")
def __str__(self):
return self.date.strftime("%d %B %Y")
class EventTime(models.Model):
event_date = models.ForeignKey(EventDate, on_delete=models.CASCADE, related_name='event_times')
time = models.TimeField(_("Event time"))
maxSubscribers = models.PositiveIntegerField(_("Max number of subscribers"), default=6)
class Meta:
verbose_name = _("Event Time")
verbose_name_plural = _("Event Times")
ordering = ['time']
constraints = [
models.UniqueConstraint(fields=['event_date', 'time'], name='unique_event_time')
]
def clean(self):
if self.pk and self.maxSubscribers < self.current_subscriber_count:
raise ValidationError({
'maxSubscribers': _('Max subscribers cannot be less than current subscriber count (%(count)d)')
% {'count': self.current_subscriber_count}
})
@property
def current_subscriber_count(self):
return self.subscribers.count() if hasattr(self, 'subscribers') else 0
def get_available_slots(self):
return max(0, self.maxSubscribers - self.current_subscriber_count)
def is_full(self):
return self.current_subscriber_count >= self.maxSubscribers
def __str__(self):
return f"{self.time.strftime('%H:%M')} ({self.get_available_slots()} places available)"
class Subscriber(models.Model):
published = models.DateTimeField(auto_now_add=True)
GENDER_CHOICES = [
('M', _('Male')),
('F', _('Female')),
]
ALTITUDE_CHOICES = [
('3000', _('3 000 m (10 000 feet)')),
('3200', _('3 200 m (10 500 feet)')),
('3500', _('3 500 m (11 500 feet)')),
]
SKYDIVER_OPTIONS = [
('tandem', 'Tandem (Beginner)'),
('solo', 'Solo'),
('experienced', 'Experienced'),
]
eventDate = models.ForeignKey(
EventDate, on_delete=models.PROTECT, related_name='subscribers', verbose_name=_("Event Date")
)
eventTime = models.ForeignKey(
EventTime, on_delete=models.PROTECT, related_name='subscribers', verbose_name=_("Event Time")
)
phone_regex = RegexValidator(
regex=r'^\+?1?\d{9,15}$',
message=_("Enter a valid phone number (e.g., +123456789). Max 15 digits.")
)
email = models.EmailField(_("Email"))
name = models.CharField(_("First Name"), max_length=100)
surname = models.CharField(_("Last name"), max_length=100)
phone = models.CharField(_("Phone"), validators=[phone_regex], max_length=17, blank=True)
birthDate = BirthdayField(_("Birth Date"))
country = CountryField(blank_label=_("(Select country)"))
region = models.CharField(_("City"), max_length=100)
gender = models.CharField(_("Gender"), max_length=1, choices=GENDER_CHOICES, default='M')
altitude = models.CharField(
_("At what altitude would you like to jump from a plane?"), max_length=5, choices=ALTITUDE_CHOICES, default='3400'
)
skydiverOption = models.CharField(
_("Are you a skydiver?"), max_length=12, choices=SKYDIVER_OPTIONS, default='tandem'
)
options = models.ManyToManyField(EventOption, verbose_name=_("Selected Options"), blank=True)
class Meta:
verbose_name = _("Subscriber")
verbose_name_plural = _("Subscribers")
def __str__(self):
return f"{self.eventDate}: {self.name} {self.surname} - {self.email}"
class Payment(models.Model):
subscriber = models.ForeignKey(Subscriber, on_delete=models.CASCADE, related_name='payments')
amount = models.DecimalField(_("Total Amount"), max_digits=10, decimal_places=2)
class Meta:
verbose_name = _("Payment")
verbose_name_plural = _("Payments")
def __str__(self):
return f"Payment for {self.subscriber.name} {self.subscriber.surname} - {self.amount}"
def calculate_total_amount(self):
event_price = self.subscriber.eventDate.event.amount
options_total = sum(option.amount for option in self.subscriber.options.all()) if self.subscriber.options.exists() else 0
return event_price + options_total
def save(self, *args, **kwargs):
self.amount = self.calculate_total_amount()
super().save(*args, **kwargs)
and this my views.py
class EventCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
model = Event
form_class = NewEventForm
template_name = "event/forms/event.html"
success_url = reverse_lazy('list_event')
success_message = _("Event created successfully.")
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.POST:
context['eventdate_formset'] = EventDateFormSet(
self.request.POST, instance=self.object)
for i, date_form in enumerate(context['eventdate_formset']):
prefix = f'time_{i}'
if date_form.instance.pk:
date_form.eventtime_formset = EventTimeFormSet(
self.request.POST, instance=date_form.instance, prefix=prefix)
else:
date_form.eventtime_formset = EventTimeFormSet(
self.request.POST, prefix=prefix)
else:
context['eventdate_formset'] = EventDateFormSet(
instance=self.object)
for i, date_form in enumerate(context['eventdate_formset']):
prefix = f'time_{i}'
if date_form.instance.pk:
date_form.eventtime_formset = EventTimeFormSet(
instance=date_form.instance, prefix=prefix)
else:
date_form.eventtime_formset = EventTimeFormSet(
prefix=prefix)
return context
def form_valid(self, form):
context = self.get_context_data()
eventdate_formset = context['eventdate_formset']
if form.is_valid() and eventdate_formset.is_valid():
self.object = form.save()
eventdate_formset.instance = self.object
eventdates = eventdate_formset.save()
for i, event_date in enumerate(eventdates):
date_form = eventdate_formset.forms[i]
if hasattr(date_form, 'eventtime_formset'):
time_formset = date_form.eventtime_formset
if time_formset.is_bound and time_formset.is_valid():
for time_form in time_formset:
if time_form.is_valid() and time_form.cleaned_data and not time_form.cleaned_data.get('DELETE', False):
time_instance = time_form.save(commit=False)
time_instance.event_date = event_date
time_instance.save()
return super().form_valid(form)
return self.form_invalid(form)
class EventUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
model = Event
form_class = NewEventForm
template_name = "event/forms/event.html"
success_message = _("Event updated successfully.")
def get_success_url(self):
return self.request.path
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.POST:
context['eventdate_formset'] = EventDateFormSet(
self.request.POST, instance=self.object)
for i, date_form in enumerate(context['eventdate_formset']):
prefix = f'time_{i}'
if date_form.instance.pk:
date_form.eventtime_formset = EventTimeFormSet(
self.request.POST, instance=date_form.instance, prefix=prefix)
else:
date_form.eventtime_formset = EventTimeFormSet(
self.request.POST, prefix=prefix)
else:
context['eventdate_formset'] = EventDateFormSet(
instance=self.object)
for i, date_form in enumerate(context['eventdate_formset']):
prefix = f'time_{i}'
if date_form.instance.pk:
date_form.eventtime_formset = EventTimeFormSet(
instance=date_form.instance, prefix=prefix)
else:
date_form.eventtime_formset = EventTimeFormSet(
prefix=prefix)
return context
def form_valid(self, form):
context = self.get_context_data()
eventdate_formset = context['eventdate_formset']
if form.is_valid() and eventdate_formset.is_valid():
self.object = form.save()
eventdate_formset.instance = self.object
eventdates = eventdate_formset.save()
for i, event_date in enumerate(eventdates):
date_form = eventdate_formset.forms[i]
if hasattr(date_form, 'eventtime_formset'):
time_formset = date_form.eventtime_formset
if time_formset.is_bound and time_formset.is_valid():
for time_form in time_formset:
if time_form.is_valid() and time_form.cleaned_data and not time_form.cleaned_data.get('DELETE', False):
time_instance = time_form.save(commit=False)
time_instance.event_date = event_date
time_instance.save()
return super().form_valid(form)
return self.form_invalid(form)
and this my forms.py
from django import forms
from datetime import datetime, timedelta
from django.forms.models import inlineformset_factory
from django.utils.translation import gettext_lazy as _
from django.db.models import Count, F
from event.models import Event, EventDate, EventTime, Subscriber, EventOption
import datetime
class NewEventForm(forms.ModelForm):
class Meta:
model = Event
fields = '__all__'
widgets = {
'name': forms.TextInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('Event name'),
'autocomplete': 'on'
}),
'options': forms.CheckboxSelectMultiple(attrs={
'class': 'form-checkbox transition duration-150 ease-in-out'
}),
'amount': forms.NumberInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('Price')
}),
'description': forms.Textarea(attrs={
'class': 'block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('Description')
}),
}
class EventDateForm(forms.ModelForm):
class Meta:
model = EventDate
fields = ['date']
widgets = {
'date': forms.DateInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': 'Date',
'type': 'date', 'required': False
}),
}
class EventTimeForm(forms.ModelForm):
class Meta:
model = EventTime
fields = ['time', 'maxSubscribers']
widgets = {
'time': forms.TimeInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': 'Time',
'type': 'time'
}),
'maxSubscribers': forms.NumberInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': 'Max Subscribers'
}),
}
EventDateFormSet = inlineformset_factory(
Event,
EventDate,
form=EventDateForm,
extra=1,
can_delete=True,
)
EventTimeFormSet = inlineformset_factory(
EventDate,
EventTime,
form=EventTimeForm,
extra=1,
can_delete=True,
)
class SubscriberForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
event_pk = kwargs.pop('event_pk', None)
super().__init__(*args, **kwargs)
if event_pk:
self.fields['eventDate'].queryset = EventDate.objects.filter(
event__pk=event_pk
).annotate(subscriber_count=Count('event_times__subscribers')
).filter(event_times__maxSubscribers__gt=F('subscriber_count')).distinct()
class Meta:
model = Subscriber
fields = '__all__'
widgets = {
'eventDate': forms.Select(attrs={
'class': 'w-full bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
}),
'name': forms.TextInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('Name')
}),
'surname': forms.TextInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('Surname')
}),
'email': forms.EmailInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('Email')
}),
'phone': forms.TextInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('Phone')
}),
'birthDate': forms.widgets.SelectDateWidget(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
},
years=range(1970, 2025),
empty_label=(_("Year"), _("Month"), _("Day")),
),
'gender': forms.RadioSelect(attrs={
'class': 'm-0',
}),
'altitude': forms.RadioSelect(attrs={
'class': 'm-0',
}),
'skydiverOption': forms.RadioSelect(attrs={
'class': 'm-0',
}),
'options': forms.CheckboxSelectMultiple(attrs={
'class': 'form-checkbox text-indigo-600 transition duration-150 ease-in-out'
}),
'country': forms.Select(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
}),
'region': forms.TextInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('City')
}),
}
class EventOptionForm(forms.ModelForm):
class Meta:
model = EventOption
fields = "__all__"
widgets = {
'name': forms.TextInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('Name'),
}),
'amount': forms.NumberInput(attrs={
'class': 'bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500',
'placeholder': _('300.00 TND')
}),
}
and this my js
{% block scripts %}
<script>
function eventForm() {
return {
addEventDate() {
const index = this.$refs.eventDates.children.length - 1;
const newForm = document.createElement('div');
newForm.innerHTML = `
<div class="event-date-form mb-4 p-4 border border-gray-300 rounded-lg" x-data="eventDateForm(${index})">
<input type="hidden" name="event_dates-${index}-id" id="id_event_dates-${index}-id">
<input type="hidden" name="event_dates-${index}-event" id="id_event_dates-${index}-event">
<div class="grid sm:grid-cols-1 md:grid-cols-2 gap-4">
<div class="mb-2">
<label for="id_event_dates-${index}-date" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Date
</label>
<input type="date" name="event_dates-${index}-date" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" id="id_event_dates-${index}-date">
</div>
</div>
<div class="mt-4 border-t pt-4">
<h4 class="text-md font-medium mb-2">Event Times</h4>
<div class="event-times" id="event-times-${index}" x-ref="eventTimes">
<input type="hidden" name="time_${index}-TOTAL_FORMS" value="0" id="id_time_${index}-TOTAL_FORMS">
<input type="hidden" name="time_${index}-INITIAL_FORMS" value="0" id="id_time_${index}-INITIAL_FORMS">
<input type="hidden" name="time_${index}-MIN_NUM_FORMS" value="0" id="id_time_${index}-MIN_NUM_FORMS">
<input type="hidden" name="time_${index}-MAX_NUM_FORMS" value="1000" id="id_time_${index}-MAX_NUM_FORMS">
</div>
<button type="button"
class="mt-2 px-3 py-2 text-xs font-medium text-center text-white bg-green-700 rounded-lg hover:bg-green-800 focus:ring-4 focus:outline-none focus:ring-green-300 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800"
@click="addEventTime(${index})">
Add event time
</button>
</div>
</div>
`;
this.$refs.eventDates.appendChild(newForm);
this.updateFormsetCount();
},
addEventTime(dateIndex) {
const timeFormset = this.$refs.eventDates.querySelector(`#event-times-${dateIndex}`);
const index = timeFormset.querySelectorAll('.event-time-form').length;
const newForm = document.createElement('div');
newForm.innerHTML = `
<div class="event-time-form mb-3 p-3 bg-gray-50 dark:bg-gray-800 rounded">
<input type="hidden" name="time_${dateIndex}-${index}-id" id="id_time_${dateIndex}-${index}-id">
<input type="hidden" name="time_${dateIndex}-${index}-event_date" id="id_time_${dateIndex}-${index}-event_date">
<div class="grid sm:grid-cols-1 md:grid-cols-2 gap-4">
<div class="mb-2">
<label for="id_time_${dateIndex}-${index}-time" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Time
</label>
<input type="time" name="time_${dateIndex}-${index}-time" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" id="id_time_${dateIndex}-${index}-time">
</div>
<div class="mb-2">
<label for="id_time_${dateIndex}-${index}-maxSubscribers" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Max Subscribers
</label>
<input type="number" name="time_${dateIndex}-${index}-maxSubscribers" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" id="id_time_${dateIndex}-${index}-maxSubscribers" value="6">
</div>
</div>
</div>
`;
timeFormset.appendChild(newForm);
this.updateFormsetCount();
},
updateFormsetCount() {
const dateFormset = this.$refs.eventDates;
const dateTotalForms = dateFormset.querySelector('[name="event_dates-TOTAL_FORMS"]');
const dateForms = dateFormset.querySelectorAll('.event-date-form');
dateTotalForms.value = dateForms.length;
dateForms.forEach((dateForm, dateIndex) => {
const timeFormset = dateForm.querySelector(`#event-times-${dateIndex}`);
if (timeFormset) {
const timeTotalForms = timeFormset.querySelector(`[name="time_${dateIndex}-TOTAL_FORMS"]`);
const timeForms = timeFormset.querySelectorAll('.event-time-form');
if (timeTotalForms) {
timeTotalForms.value = timeForms.length;
}
}
});
}
}
}
function eventDateForm(index) {
return {
addEventTime() {
const timeFormset = this.$refs.eventTimes;
const index = timeFormset.querySelectorAll('.event-time-form').length;
const newForm = document.createElement('div');
newForm.innerHTML = `
<div class="event-time-form mb-3 p-3 bg-gray-50 dark:bg-gray-800 rounded">
<input type="hidden" name="time_${index}-${index}-id" id="id_time_${index}-${index}-id">
<input type="hidden" name="time_${index}-${index}-event_date" id="id_time_${index}-${index}-event_date">
<div class="grid sm:grid-cols-1 md:grid-cols-2 gap-4">
<div class="mb-2">
<label for="id_time_${index}-${index}-time" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Time
</label>
<input type="time" name="time_${index}-${index}-time" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" id="id_time_${index}-${index}-time">
</div>
<div class="mb-2">
<label for="id_time_${index}-${index}-maxSubscribers" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Max Subscribers
</label>
<input type="number" name="time_${index}-${index}-maxSubscribers" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" id="id_time_${index}-${index}-maxSubscribers" value="6">
</div>
</div>
</div>
`;
timeFormset.appendChild(newForm);
this.updateFormsetCount();
},
updateFormsetCount() {
const dateFormset = this.$refs.eventDates;
const dateTotalForms = dateFormset.querySelector('[name="event_dates-TOTAL_FORMS"]');
const dateForms = dateFormset.querySelectorAll('.event-date-form');
dateTotalForms.value = dateForms.length;
dateForms.forEach((dateForm, dateIndex) => {
const timeFormset = dateForm.querySelector(`#event-times-${dateIndex}`);
if (timeFormset) {
const timeTotalForms = timeFormset.querySelector(`[name="time_${dateIndex}-TOTAL_FORMS"]`);
const timeForms = timeFormset.querySelectorAll('.event-time-form');
if (timeTotalForms) {
timeTotalForms.value = timeForms.length;
}
}
});
}
}
}
</script>
{% endblock scripts %}
and thanks for any help