Add support for using fieldsets in backend forms
authorMagnus Hagander <magnus@hagander.net>
Mon, 2 Jul 2018 10:28:03 +0000 (12:28 +0200)
committerMagnus Hagander <magnus@hagander.net>
Mon, 2 Jul 2018 10:28:03 +0000 (12:28 +0200)
This will help make the big forms a lot more readable

postgresqleu/confreg/backendforms.py
template/confreg/admin_backend_form_content.html
template/confreg/admin_backend_form_field.html [new file with mode: 0644]

index 092dbabd174f0c56ad0ca9df598019ccf47a947d..b5721a6bb9b0259c2279eca2f08c7665601d3a14 100644 (file)
@@ -51,6 +51,7 @@ class BackendForm(ConcurrentProtectedModelForm):
        file_fields = []
        linked_objects = {}
        auto_cascade_delete_to = []
+       fieldsets = []
 
        def __init__(self, conference, *args, **kwargs):
                self.conference = conference
@@ -70,6 +71,15 @@ class BackendForm(ConcurrentProtectedModelForm):
                self.fix_fields()
                self.fix_selectize_fields(**kwargs)
 
+               # Runtime validate fieldsets. It's ugly as fsck to do this at runtime,
+               # but meh, this isn't used that often so...
+               if self.fieldsets:
+                       all_fields = set([f for f in self.fields if not f == '_validator'])
+                       all_fieldsetted_fields = set(reduce(lambda x,y: x+y, [v['fields'] for v in self.fieldsets]))
+                       missing = all_fields.difference(all_fieldsetted_fields)
+                       if missing:
+                               raise Exception("ERROR: fields %s are not in a fieldset" % ", ".join(missing))
+
                for k,v in self.fields.items():
                        # Adjust widgets
                        if isinstance(v, django.forms.fields.DateField):
@@ -126,6 +136,15 @@ class BackendForm(ConcurrentProtectedModelForm):
                        return self.verbose_field_names[f]
                return self.Meta.model._meta.get_field(f).verbose_name.capitalize()
 
+       @property
+       def validator_field(self):
+               return self['_validator']
+
+
+       def get(self, name, default=None):
+               # Implement the get operator, for template functions to get a field
+               return self[name]
+
 class BackendConferenceForm(BackendForm):
        class Meta:
                model = Conference
index 04cafcf292c1260b0ab4c2c8b1c62bcf92314224..aaf734dad10c2b3a7d4363fe6d7849b2aa38e8a5 100644 (file)
@@ -1,33 +1,25 @@
-{%load formutil%}
+{%load dictutil%}
 {%if form.non_field_errors%}
  <div class="alert alert-danger">{{form.non_field_errors}}</div>
 {%endif%}
 {%if note%}
 <div class="alert alert-info">{{note|safe}}</div>
 {%endif%}
- {%for field in form%}
- {%if not field.is_hidden%}
-<div class="form-group">
-   {{field|label_class:"control-label col-lg-3"}}
-<div class="col-lg-9 controls">
-{%if field|ischeckbox%}<div class="row"><div class="col-lg-8 backendform_checkbox">{%else%}{%endif%}
-  {%if field.errors %}
-   {%for e in field.errors%}
- <div class="alert alert-danger">{{e}}</div>
-   {%endfor%}
-  {%endif%}
-{%if not field.name in form.selectize_multiple_fields and not field|ischeckbox%}
-{{field|field_class:"form-control"}}
-{%else%}
-{{field}}
-{%endif%}
-{%if field|ischeckbox%}</div></div>{%endif%}
-{%if field.help_text%}<div>{{field.help_text|safe}}</div>{%endif%}</div>
- </div>
- {%else%}{# field.is_hidden #}
-{{field}}
- {%endif%}
+{%if form.fieldsets%}
+{{form.validator_field}}
+{%for fieldset in form.fieldsets%}
+<fieldset id="{{fieldset.id}}">
+  <legend>{{fieldset.legend}}</legend>
+{%for field in fieldset.fields%}
+  {%include "confreg/admin_backend_form_field.html" with field=form|dictlookup:field %}
 {%endfor%}
+</fieldset>
+{%endfor%}
+{%else%}{%comment%} No fieldsets, so render the full form{%endcomment%}
+{%for field in form%}
+{%include "confreg/admin_backend_form_field.html"%}
+{%endfor%}
+{%endif%}
 
 {%for url, handler, entries in linked %}
 <div class="form-group">
diff --git a/template/confreg/admin_backend_form_field.html b/template/confreg/admin_backend_form_field.html
new file mode 100644 (file)
index 0000000..7c72762
--- /dev/null
@@ -0,0 +1,22 @@
+{%load formutil%}
+ {%if not field.is_hidden%}
+<div class="form-group">
+   {{field|label_class:"control-label col-lg-3"}}
+<div class="col-lg-9 controls">
+{%if field|ischeckbox%}<div class="row"><div class="col-lg-8 backendform_checkbox">{%else%}{%endif%}
+  {%if field.errors %}
+   {%for e in field.errors%}
+ <div class="alert alert-danger">{{e}}</div>
+   {%endfor%}
+  {%endif%}
+{%if not field.name in form.selectize_multiple_fields and not field|ischeckbox%}
+{{field|field_class:"form-control"}}
+{%else%}
+{{field}}
+{%endif%}
+{%if field|ischeckbox%}</div></div>{%endif%}
+{%if field.help_text%}<div>{{field.help_text|safe}}</div>{%endif%}</div>
+ </div>
+ {%else%}{# field.is_hidden #}
+{{field}}
+ {%endif%}