Skip to content

Commit

Permalink
Restarting to work on that functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Ash-Crow committed Jun 25, 2024
1 parent 2e85859 commit f0c078f
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 3 deletions.
1 change: 1 addition & 0 deletions config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
INSTALLED_APPS = [
"storages",
"dashboard",
"wagtail.contrib.forms",
"wagtail.contrib.redirects",
"wagtail.contrib.settings",
"wagtail.embeds",
Expand Down
125 changes: 125 additions & 0 deletions content_manager/migrations/0035_formpage_formfield.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# Generated by Django 5.0.6 on 2024-06-24 14:34

import django.db.models.deletion
import modelcluster.fields
import wagtail.contrib.forms.models
import wagtail.fields
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("content_manager", "0034_alter_contentpage_body"),
("wagtailcore", "0093_uploadedfile"),
]

operations = [
migrations.CreateModel(
name="FormPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
(
"to_address",
models.CharField(
blank=True,
help_text="Optional - form submissions will be emailed to these addresses. Separate multiple addresses by comma.",
max_length=255,
validators=[wagtail.contrib.forms.models.validate_to_address],
verbose_name="to address",
),
),
("from_address", models.EmailField(blank=True, max_length=255, verbose_name="from address")),
("subject", models.CharField(blank=True, max_length=255, verbose_name="subject")),
("intro", wagtail.fields.RichTextField(blank=True)),
("thank_you_text", wagtail.fields.RichTextField(blank=True)),
],
options={
"verbose_name": "Page de formulaire",
"verbose_name_plural": "Pages de formulaire",
},
bases=(wagtail.contrib.forms.models.FormMixin, "wagtailcore.page", models.Model),
),
migrations.CreateModel(
name="FormField",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("sort_order", models.IntegerField(blank=True, editable=False, null=True)),
(
"clean_name",
models.CharField(
blank=True,
default="",
help_text="Safe name of the form field, the label converted to ascii_snake_case",
max_length=255,
verbose_name="name",
),
),
(
"label",
models.CharField(help_text="The label of the form field", max_length=255, verbose_name="label"),
),
(
"field_type",
models.CharField(
choices=[
("singleline", "Single line text"),
("multiline", "Multi-line text"),
("email", "Email"),
("number", "Number"),
("url", "URL"),
("checkbox", "Checkbox"),
("checkboxes", "Checkboxes"),
("dropdown", "Drop down"),
("multiselect", "Multiple select"),
("radio", "Radio buttons"),
("date", "Date"),
("datetime", "Date/time"),
("hidden", "Hidden field"),
],
max_length=16,
verbose_name="field type",
),
),
("required", models.BooleanField(default=True, verbose_name="required")),
(
"choices",
models.TextField(
blank=True,
help_text="Comma or new line separated list of choices. Only applicable in checkboxes, radio and dropdown.",
verbose_name="choices",
),
),
(
"default_value",
models.TextField(
blank=True,
help_text="Default value. Comma or new line separated values supported for checkboxes.",
verbose_name="default value",
),
),
("help_text", models.CharField(blank=True, max_length=255, verbose_name="help text")),
(
"page",
modelcluster.fields.ParentalKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="form_fields",
to="content_manager.formpage",
),
),
],
options={
"ordering": ["sort_order"],
"abstract": False,
},
),
]
103 changes: 100 additions & 3 deletions content_manager/models.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from django.db import models
from django.forms.widgets import Textarea
from django.forms import widgets
from django.template.response import TemplateResponse
from django.utils.translation import gettext_lazy as _
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
from modelcluster.tags import ClusterTaggableManager
from taggit.models import Tag as TaggitTag, TaggedItemBase
from wagtail.admin.panels import FieldPanel, InlinePanel, MultiFieldPanel, ObjectList, TabbedInterface
from wagtail.admin.panels import FieldPanel, FieldRowPanel, InlinePanel, MultiFieldPanel, ObjectList, TabbedInterface
from wagtail.contrib.forms.models import AbstractEmailForm, AbstractFormField
from wagtail.contrib.forms.panels import FormSubmissionsPanel
from wagtail.contrib.settings.models import BaseSiteSetting, register_setting
from wagtail.fields import RichTextField
from wagtail.images import get_image_model_string
Expand Down Expand Up @@ -47,7 +50,7 @@ class MonospaceField(models.TextField):
"""

def formfield(self, **kwargs):
kwargs["widget"] = Textarea(
kwargs["widget"] = widgets.Textarea(
attrs={
"rows": 12,
"class": "monospace",
Expand Down Expand Up @@ -332,3 +335,97 @@ def get_categories(self):

class Meta:
verbose_name = _("Mega menu")


class FormField(AbstractFormField):
FORM_FIELD_CHOICES = (
("singleline", _("Single line text")),
("multiline", _("Multi-line text")),
("email", _("Email")),
("number", _("Number")),
("url", _("URL")),
("checkbox", _("Checkbox")),
("cmsfr_checkboxes", _("Checkboxes")),
("dropdown", _("Drop down")),
("cmsfr_radio", _("Radio buttons")),
("cmsfr_date", _("Date")),
("cmsfr_datetime", _("Date/time")),
("hidden", _("Hidden field")),
)

page = ParentalKey("FormPage", on_delete=models.CASCADE, related_name="form_fields")


class FormPage(AbstractEmailForm):
intro = RichTextField(blank=True)
thank_you_text = RichTextField(blank=True)

content_panels = AbstractEmailForm.content_panels + [
FormSubmissionsPanel(),
FieldPanel("intro", heading="Introduction"),
InlinePanel("form_fields", label="Champs de formulaire"),
FieldPanel("thank_you_text", heading="Texte de remerciement"),
MultiFieldPanel(
[
FieldRowPanel(
[
FieldPanel("from_address", classname="col6"),
FieldPanel("to_address", classname="col6"),
]
),
FieldPanel("subject"),
],
"Courriel",
help_text="Facultatif",
),
]

class Meta:
verbose_name = "Page de formulaire"
verbose_name_plural = "Pages de formulaire"

def serve(self, request, *args, **kwargs):
# These input widgets don't need the fr-input class
if request.method == "POST":
form = self.get_form(request.POST, request.FILES, page=self, user=request.user)

if form.is_valid():
form_submission = self.process_form_submission(form)
return self.render_landing_page(request, form_submission, *args, **kwargs)
else:
form = self.get_form(page=self, user=request.user)

WIDGETS_NO_FR_INPUT = [
widgets.CheckboxInput,
widgets.FileInput,
widgets.ClearableFileInput,
]

for visible in form.visible_fields():
"""
Depending on the widget, we have to add some classes:
- on the outer group
- on the form field itsef
If a class is already set, we don't force the DSFR-specific classes.
"""
if "class" not in visible.field.widget.attrs:
if type(visible.field.widget) in [
widgets.Select,
widgets.SelectMultiple,
]:
visible.field.widget.attrs["class"] = "fr-select"
visible.field.widget.group_class = "fr-select-group"
elif isinstance(visible.field.widget, widgets.DateInput):
visible.field.widget.attrs["class"] = "fr-input"
visible.field.widget.attrs["type"] = "date"
elif isinstance(visible.field.widget, widgets.RadioSelect):
visible.field.widget.attrs["dsfr"] = "dsfr"
visible.field.widget.group_class = "fr-radio-group"
elif isinstance(visible.field.widget, widgets.CheckboxSelectMultiple):
visible.field.widget.attrs["dsfr"] = "dsfr"
elif type(visible.field.widget) not in WIDGETS_NO_FR_INPUT:
visible.field.widget.attrs["class"] = "fr-input"

context = self.get_context(request)
context["form"] = form
return TemplateResponse(request, self.get_template(request), context)
24 changes: 24 additions & 0 deletions content_manager/templates/content_manager/form_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{% extends "base.html" %}

{% load wagtailcore_tags dsfr_tags %}

{% block content %}
<div class="fr-container fr-my-6w">
<div class="fr-grid-row fr-grid-row--center">
<div class="fr-col-md-8">
<h1>{{ page.title }}</h1>
{{ page.intro|richtext }}
<form action="{% pageurl page %}" method="post">
{% csrf_token %}
{% dsfr_form %}
<input class="fr-btn" type="submit">
<ul>
{% for field in form %}
<li>{{ field.label }}, {{ field.type }}, {{ field.field.widget.attrs }} {{ field.field.widget }}</li>
{% endfor %}
</ul>
</form>
</div>
</div>
</div>
{% endblock content %}
10 changes: 10 additions & 0 deletions content_manager/templates/content_manager/form_page_landing.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% extends "base.html" %}

{% load wagtailcore_tags %}

{% block content %}
<div class="fr-container fr-mt-6w">
<h1>{{ page.title }}</h1>
{{ page.thank_you_text|richtext }}
</div>
{% endblock content %}

0 comments on commit f0c078f

Please sign in to comment.