diff --git a/home/forms.py b/home/forms.py index a6cb16aa8f06e7889a88b56914bd2fe818d6b4e3..a0ba31c5e92098bdc769eb4c58b29bed4e58111f 100644 --- a/home/forms.py +++ b/home/forms.py @@ -1,4 +1,5 @@ from django import forms +from django.core.exceptions import ValidationError from home.models import ActivityList, InterludesParticipant from shared.forms import FormRenderMixin @@ -30,3 +31,22 @@ class ActivityForm(FormRenderMixin, forms.ModelForm): class Meta: model = ActivityList fields = ("activity",) + +class BaseActivityFormSet(forms.BaseFormSet): + """Form set that fails if duplicate activities""" + def clean(self): + """Checks for duplicate activities""" + if any(self.errors): + # Don't bother validating the formset unless each form is valid on its own + return + activities = [] + for form in self.forms: + if self.can_delete and self._should_delete_form(form): + continue + activity = form.cleaned_data.get('activity') + if activity is None: + continue + if activity in activities: + print(activity) + raise ValidationError("Vous ne pouvez pas sélectionner une même activtté plusieurs fois") + activities.append(activity) diff --git a/home/static/css/style.css b/home/static/css/style.css index bef1b44450808f2b6fa3ff81df5ec31a01487097..bd20b342310caf4de05655d3240322b2d7710ce1 100644 --- a/home/static/css/style.css +++ b/home/static/css/style.css @@ -9,7 +9,6 @@ html, body { background-color: #dddddd; color: #333; - font-size: 18px; font-weight: 300; line-height: 1.5; font-family: Arial, Roboto, Helvetica, sans-serif; @@ -174,6 +173,7 @@ span.helptext { .button, .button:link, .button:visited, input[type=submit] { color: white; text-decoration: none; + font-size: 1em; background-color: var(--color_bg_1); padding: 7px 10px; margin: 5px; diff --git a/home/templates/inscription/form.html b/home/templates/inscription/form.html index a75b84b139f7ad7f64a5481f221396498809f528..7a0b25202706ffc67babda50a8e58d7c1057f246 100644 --- a/home/templates/inscription/form.html +++ b/home/templates/inscription/form.html @@ -3,10 +3,6 @@ {% block nav_inscription %}current{% endblock %} -{% block "head" %} - <!--<script src="{% static 'js/formset.js' %}"></script>--> -{% endblock %} - {% block "content" %} <h2>Inscriptions</h2> <form id="main_form" method="post" action="{% url 'inscription' %}"> @@ -14,6 +10,13 @@ {{ form.as_p }} <h3>Choix d'activités</h3> + + <p>Saissisez les activités auquelles vous voulez vous inscrire, par ordre de préférence.</p> + + {% if formset.non_form_errors %} + {{ formset.non_form_errors }} + {% endif %} + {{ formset.management_data }} {{ formset.management_form }} {% for form in formset %} @@ -50,6 +53,7 @@ function add_new_form(event) { new_form.innerHTML = new_form.innerHTML.replace(form_regex, `form-${form_count}-`); // add it and increment form total main_form.insertBefore(new_form, button_add_activity); + new_form.querySelector("select").value = ""; total_forms.setAttribute("value", `${form_count+1}`); } diff --git a/home/views.py b/home/views.py index b2f6b73c1a1276ad3c433f5e0a41759ea329eadc..e12779360847b3bdd45652e4b0f8d8c89aaac7a9 100644 --- a/home/views.py +++ b/home/views.py @@ -1,13 +1,13 @@ from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.sitemaps import Sitemap -from django.forms import modelformset_factory +from django.forms import formset_factory from django.shortcuts import redirect, render from django.urls import reverse from django.views.generic import UpdateView, TemplateView, View from home.models import ActivityList, InterludesActivity -from home.forms import ActivityForm, InscriptionForm +from home.forms import ActivityForm, BaseActivityFormSet, InscriptionForm from site_settings.models import SiteSettings @@ -41,35 +41,50 @@ class RegisterSignIn(TemplateView): l'utilisateur n'est pas connecté""" template_name = "inscription/signin.html" -class RegisterUpdateView(LoginRequiredMixin, UpdateView): +class RegisterUpdateView(LoginRequiredMixin, TemplateView): """Vue pour s'inscrire et modifier son inscription""" template_name = "inscription/form.html" form_class = InscriptionForm - formset = modelformset_factory(ActivityList, form=ActivityForm, extra=3) + formset_class = formset_factory(form=ActivityForm, extra=3, formset=BaseActivityFormSet) + + @staticmethod + def get_activities(participant): + activities = ActivityList.objects.filter(participant=participant).order_by("priority") + return [{"activity": act.activity} for act in activities] + + @staticmethod + def set_activities(participant, formset): + # delete old activites + ActivityList.objects.filter(participant=participant).delete() + + priority = 0 + for form in formset: + data = form.cleaned_data + if data: + activity = data["activity"] + ActivityList(priority=priority, participant=participant, activity=activity).save() + priority += 1 + + def get(self, request, *args, **kwargs): + participant = request.user.profile + activities = self.get_activities(participant) + form = self.form_class(instance=participant) + formset = self.formset_class(initial=activities) + context = {"form": form, "formset": formset} + return render(request, self.template_name, context) - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context["formset"] = self.formset(queryset=ActivityList.objects.none()) - return context - - def get_object(self): - return self.request.user.profile - - def get_success_url(self): - return reverse("accounts:profile") + def post(self, request, *args, **kwargs): + form = self.form_class(request.POST, instance=request.user.profile) + formset = self.formset_class(request.POST) + if not (form.is_valid() and formset.is_valid()): + context = {"form": form, "formset": formset} + return render(request, self.template_name, context) - def form_valid(self, form): - messages.success(self.request, "Votre inscription a été enregistrée") - return super().form_valid(form) + form.save() + self.set_activities(request.user.profile, formset) - def post(self, request, *args, **kwargs): - form = self.form_class(request.POST) - formset = self.formset(request.POST) - if formset.is_valid(): - print("\n\n{} {}\n\n".format(len(formset), formset)) - else: - print("\n\nInvalid\n\n") - return super().post(request, *args, **kwargs) + messages.success(request, "Votre inscription a bien été enregistrée") + return redirect("accounts:profile", permanent=False) class RegisterView(View): """Vue pour l'inscription