Skip to content
This repository has been archived by the owner on Sep 5, 2019. It is now read-only.

Commit

Permalink
Adds the ability to move in a form class
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Krienbühl committed Sep 8, 2016
1 parent bd7625f commit 7f41bb7
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 6 deletions.
4 changes: 4 additions & 0 deletions HISTORY.rst
@@ -1,5 +1,9 @@
Changelog
---------

- Adds the ability to move in a form class.
[href]

0.13.0 (2016-08-30)
~~~~~~~~~~~~~~~~~~~

Expand Down
11 changes: 9 additions & 2 deletions onegov/form/__init__.py
Expand Up @@ -10,7 +10,13 @@
FormSubmissionCollection,
FormDefinitionCollection
)
from onegov.form.core import FieldDependency, Form, merge_forms, with_options
from onegov.form.core import (
FieldDependency,
Form,
merge_forms,
move_fields,
with_options,
)
from onegov.form.display import render_field
from onegov.form.models import (
FormDefinition,
Expand All @@ -32,8 +38,9 @@
'FormSubmissionCollection',
'FormSubmissionFile',
'merge_forms',
'move_fields',
'parse_form',
'PendingFormSubmission',
'render_field',
'with_options'
'with_options',
]
51 changes: 48 additions & 3 deletions onegov/form/core.py
Expand Up @@ -447,17 +447,62 @@ class Merged(*forms):
class MergedForm(*forms):
pass

processed = set()
fields_in_order = (
name for cls in forms for name, field
in utils.get_fields_from_class(cls)
)

return enforce_order(MergedForm, fields_in_order)


def enforce_order(form_class, fields_in_order):
""" Takes a list of fields used in a form_class and enforces the
order of those fields.
If not all fields in the form are given, the resulting order is undefined.
"""

# XXX to make sure the field order of the existing class remains
# unchanged, we need to instantiate the class once (wtforms seems
# to do some housekeeping somehwere)
form_class()

class EnforcedOrderForm(form_class):
pass

processed = set()

for counter, name in enumerate(fields_in_order, start=1):
if name in processed:
continue

getattr(MergedForm, name).creation_counter = counter
getattr(EnforcedOrderForm, name).creation_counter = counter
processed.add(name)

return MergedForm
return EnforcedOrderForm


def move_fields(form_class, fields, after):
""" Reorders the given fields (given by name) by inserting them directly
after the given field.
If ``after`` is None, the fields are moved to the end.
"""

fields_in_order = []

for name, _ in utils.get_fields_from_class(form_class):
if name in fields:
continue

fields_in_order.append(name)

if name == after:
fields_in_order.extend(fields)

if after is None:
fields_in_order.extend(fields)

return enforce_order(form_class, fields_in_order)
15 changes: 14 additions & 1 deletion onegov/form/tests/test_core.py
@@ -1,4 +1,4 @@
from onegov.form import Form, merge_forms, with_options
from onegov.form import Form, merge_forms, with_options, move_fields
from wtforms import RadioField, StringField, TextAreaField, validators
from wtforms.fields.html5 import EmailField
from wtforms.validators import InputRequired
Expand Down Expand Up @@ -332,3 +332,16 @@ def is_valid_user(self):
assert full.is_valid_name()
assert full.is_valid_coordinate()
assert full.is_valid_user()


def test_move_fields():

class Test(Form):
a = StringField('a')
b = StringField('b')
c = StringField('c')

Moved = move_fields(Test, ['a'], None)

assert list(Test()._fields.keys()) == ['a', 'b', 'c']
assert list(Moved()._fields.keys()) == ['b', 'c', 'a']

0 comments on commit 7f41bb7

Please sign in to comment.