]> git.ipfire.org Git - people/ms/westferry.git/commitdiff
forms: Refactor classes
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 5 Dec 2021 14:41:42 +0000 (14:41 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 5 Dec 2021 14:41:42 +0000 (14:41 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/templates/modules/forms/fieldset.html
src/templates/modules/forms/index.html
src/westferry/ui/forms.py

index 0ea946991ad8f43ac2577c216caf3efbe49a0b45..c1ef4c0b6d8b7b3b18c649b7f347cac571800ce1 100644 (file)
@@ -9,5 +9,5 @@
                </p>
        {% end %}
 
-       {% module FormElements(fs) %}
+       {% module FormElements(fs.elements) %}
 </fieldset>
index 1992ac2c900e54edacc26e006905500c26742894..34e7c3df26df45fb08769ffc2ec7bf7f18991810 100644 (file)
@@ -1,7 +1,7 @@
-<form method="{{ f.method }}" action="{{ f.action }}">
+<form method="{{ form.method }}" action="{{ form.action }}">
        {% raw xsrf_form_html() %}
 
-       {% module FormElements(f) %}
+       {% module FormElements(form.elements) %}
 
-       <button type="submit" class="primary button">{{ f.submit_text or _("Submit") }}</button>
+       <button type="submit" class="primary button">{{ form.submit_text or _("Submit") }}</button>
 </form>
index ec4bfcda014e2984b89899e787359a947b9f34f0..6f2f787ac59fda199e348e58277837779725ad53 100644 (file)
 #                                                                             #
 ###############################################################################
 
-from ..backend import forms
 from . import base
 
-class _Form(object):
-       def __init__(self, form):
+class Form(object):
+       def __init__(self, handler, method="POST", action="",
+                       form=None, label=None, help=None, disabled=False):
+               self.handler = handler
+               self.method = method
+               self.action = action
                self.form = form
-               self._elements = []
+               self.label = label
+               self.help = help
+
+               self.elements = []
 
                # Is this form disabled?
-               self.disabled = False
+               self.disabled = disabled
 
        def __iter__(self):
                """
                        Iterating over a form will iterate over its elements.
                """
-               return iter(self._elements)
+               for element in self.elements:
+                       yield element
 
-       @property
-       def parent_form(self):
-               if self.form:
-                       return self.form.parent_form
+                       if isinstance(element, Form):
+                               for e in element:
+                                       yield e
+
+       def export(self):
+               """
+                       Returns a dictionary with all keys and values
+                       of the form.
+               """
+               ret = {}
 
-               return self
+               for element in self:
+                       # Skip any sub-form elements
+                       if isinstance(element, Form):
+                               continue
 
-       @property
-       def elements(self):
-               for e in self._elements:
-                       if isinstance(e, _Form):
-                               for i in e._elements:
-                                       yield i
+                       ret[element.name] = element.value
+
+               return ret
+
+       # Sub-Forms
 
-                       else:
-                               yield e
+       def _add_subform(self, cls, *args, **kwargs):
+               form = cls(self.handler, *args, form=self, **kwargs)
+               self.elements.append(form)
 
-       def _add_element(self, element):
+               return form
+
+       def add_group(self, *args, **kwargs):
+               return self._add_subform(Group, *args, **kwargs)
+
+       def add_fieldset(self, *args, **kwargs):
+               return self._add_subform(Fieldset, *args, **kwargs)
+
+       # Elements
+
+       def _add_element(self, cls, *args, **kwargs):
                """
                        Adds a new form element to this form.
                """
-               assert isinstance(element, Element)
-               assert not element in self.elements
-
-               self._elements.append(element)
+               element = cls(self,  *args, **kwargs)
+               self.elements.append(element)
 
-       def _add_element_class(self, cls, *args, **kwargs):
-               e = cls(self, *args, **kwargs)
-               self._add_element(e)
-
-               return e
+               return element
 
        def get_element_by_name(self, name):
                """
                        Returns the element with the given name (if any).
                """
-               for e in self.elements:
-                       if e.name == name:
-                               return e
+               for element in self:
+                       if element.name == name:
+                               return element
 
        # Have a shortcut to find elements by their name quickly.
-       get = get_element_by_name
+       __getattr__ = get_element_by_name
 
        def add_text_input(self, *args, **kwargs):
                """
-                       Creates a new text input.
+                       Creates a new text input
                """
-               return self._add_element_class(TextInput, *args, **kwargs)
+               return self._add_element(TextInput, *args, **kwargs)
 
        def add_multiline_text_input(self, *args, **kwargs):
                """
-                       Creates a new multiline text input.
+                       Creates a new multiline text input
                """
-               return self._add_element_class(MultilineTextInput, *args, **kwargs)
+               return self._add_element(MultilineTextInput, *args, **kwargs)
 
        def add_password_input(self, *args, **kwargs):
                """
-                       Creates a new password input.
+                       Creates a new password input
                """
-               return self._add_element_class(PasswordInput, *args, **kwargs)
+               return self._add_element(PasswordInput, *args, **kwargs)
 
        def add_yesno_input(self, *args, **kwargs):
                """
-                       Creates a new yes/no input.
+                       Creates a new yes/no input
                """
-               return self._add_element_class(YesNoInput, *args, **kwargs)
+               return self._add_element(YesNoInput, *args, **kwargs)
 
        def add_single_choice_input(self, *args, **kwargs):
                """
-                       Creates a new single choice input.
+                       Creates a new single choice input
                """
-               return self._add_element_class(SingleChoiceInput, *args, **kwargs)
+               return self._add_element(SingleChoiceInput, *args, **kwargs)
 
        def add_multiple_choice_input(self, *args, **kwargs):
                """
-                       Creates a new multiple choice input.
+                       Creates a new multiple choice input
                """
-               return self._add_element_class(MultipleChoiceInput, *args, **kwargs)
-
-       def _get_value(self, *args, **kwargs):
-               return self.parent_form._get_value(*args, **kwargs)
+               return self._add_element(MultipleChoiceInput, *args, **kwargs)
 
 
-class FormGroupMixin(object):
-       def add_group(self, *args, **kwargs):
-               group = Group(self, *args, **kwargs)
-               self._elements.append(group)
-
-               return group
-
-
-class Form(_Form, FormGroupMixin):
-       def __init__(self, handler, method="POST", action=""):
-               _Form.__init__(self, None)
-               self.handler = handler
-
-               self.method = method
-               self.action = action
-
-               # Text that is shown on the submit button
-               self.submit_text = None
-
-       def add_fieldset(self, *args, **kwargs):
-               fs = Fieldset(self, *args, **kwargs)
-               self._elements.append(fs)
-
-               return fs
-
-       def export(self):
-               """
-                       Returns a dictionary with all keys and values
-                       of the form.
-               """
-               ret = {}
-
-               for e in self.elements:
-                       ret[e.name] = e.value
-
-               return ret
-
-       def _get_value(self, name, default=None):
-               return self.handler.get_argument(name, default)
-
-
-class Fieldset(_Form, FormGroupMixin):
-       def __init__(self, *args, label=None, help=None, **kwargs):
-               _Form.__init__(self, *args, **kwargs)
-
-               self.label = label
-               self.help = help
+class Fieldset(Form):
+       pass
 
 
 class FormFieldsetModule(base.BaseUIModule):
@@ -173,19 +145,16 @@ class FormFieldsetModule(base.BaseUIModule):
                return self.render_string("modules/forms/fieldset.html", fs=fieldset)
 
 
-class Group(_Form):
-       def __init__(self, *args, label=None, **kwargs):
-               _Form.__init__(self, *args, **kwargs)
-
-               self.label = label
-               self.help = None
+class Group(Form):
+       pass
 
 
 class Element(object):
        # The element type
        type = None
 
-       def __init__(self, form, name=None, label=None, default=None, **kwargs):
+       def __init__(self, form, name=None, label=None, default=None,
+                       disabled=False, readonly=False, **kwargs):
                assert self.type
 
                self.form = form
@@ -194,25 +163,16 @@ class Element(object):
                self.default = default
 
                # Is this element editable?
-               self.disabled = False
-               self.readonly = False
+               self.disabled = disabled
+               self.readonly = readonly
 
                # Help text
                self.help = None
 
-               # Set defaults for inheriting classes
-               self._set_defaults()
-
-               # Set args
-               for k, v in kwargs.items():
-                       setattr(self, k, v)
+               # Call initializer for inheriting classes
+               self.initialize(**kwargs)
 
-               self.init(**kwargs)
-
-       def _set_defaults(self):
-               pass
-
-       def init(self, *args, **kwargs):
+       def initialize(self):
                pass
 
        @property
@@ -220,10 +180,7 @@ class Element(object):
                """
                        Returns the value that the user entered for this element.
                """
-               return self.get_value()
-
-       def get_value(self):
-               return self.form._get_value(self.name, self.default)
+               return self.form.handler.get_argument(self.name, self.default)
 
 
 class SingleChoiceInput(Element):
@@ -236,8 +193,7 @@ class MultipleChoiceInput(Element):
 
 class FormModule(base.BaseUIModule):
        def render(self, form):
-               return self.render_string("modules/forms/index.html",
-                       f=form, forms=forms)
+               return self.render_string("modules/forms/index.html", form=form)
 
 
 class FormElementsModule(base.BaseUIModule):
@@ -248,19 +204,11 @@ class FormElementsModule(base.BaseUIModule):
 class TextInput(Element):
        type = "text"
 
-       def _set_defaults(self):
-               self.prefix = None
-               self.suffix = None
-
-               self._placeholder = None
+       def initialize(self, prefix=None, suffix=None, placeholder=None):
+               self.prefix = prefix
+               self.suffix = suffix
 
-       def get_placeholder(self):
-               return self._placeholder or self.label
-
-       def set_placeholder(self, placeholder):
-               self._placeholder = placeholder
-
-       placeholder = property(get_placeholder, set_placeholder)
+               self.placeholder = placeholder or self.label
 
 
 class TextInputModule(base.BaseUIModule):
@@ -277,11 +225,13 @@ class PasswordInput(TextInput):
 class MultilineTextInput(TextInput):
        type = "multiline-text"
 
-       def _set_defaults(self):
-               TextInput._set_defaults(self)
+       DEFAULT_LINES = 3
+
+       def initialize(self, lines=DEFAULT_LINES, **kwargs):
+               super().initialize(**kwargs)
+
+               self.lines = lines
 
-               # Default number of rows
-               self.lines = 3
 
 
 class MultilineTextInputModule(base.BaseUIModule):
@@ -294,8 +244,8 @@ class MultilineTextInputModule(base.BaseUIModule):
 class YesNoInput(Element):
        type = "yesno"
 
-       def _set_defaults(self):
-               self.description = None
+       def initialize(self, description=None):
+               self.description = description
 
        def get_value(self):
                value = Element.get_value(self)