add conditions to fields (#19752)
This commit is contained in:
parent
d46c4c0451
commit
668a04f96a
|
@ -5048,3 +5048,30 @@ def test_form_and_category_same_slug(pub):
|
|||
# check we get to the form, not the category
|
||||
resp = get_app(pub).get('/foobar/')
|
||||
assert resp.form
|
||||
|
||||
def test_field_condition(pub):
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'Foo'
|
||||
formdef.fields = [
|
||||
fields.StringField(type='string', id='1', label='Bar', size='40',
|
||||
required=True,
|
||||
condition={'type': 'django', 'value': '1'}),
|
||||
fields.StringField(type='string', id='2', label='Foo', size='40',
|
||||
required=True,
|
||||
condition={'type': 'django', 'value': '0'}),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
resp = get_app(pub).get('/foo/')
|
||||
assert 'f1' in resp.form.fields
|
||||
assert 'f2' not in resp.form.fields
|
||||
resp.form['f1'] = 'hello'
|
||||
resp = resp.form.submit('submit')
|
||||
assert 'Check values then click submit.' in resp.body
|
||||
assert 'name="f1"' in resp.body
|
||||
assert 'name="f2"' not in resp.body
|
||||
resp = resp.form.submit('submit')
|
||||
resp = resp.follow()
|
||||
assert '<span class="label">Bar</span>' in resp.body
|
||||
assert '<span class="label">Foo</span>' not in resp.body
|
||||
|
|
|
@ -457,3 +457,14 @@ def test_required_authentication_contexts():
|
|||
formdef.required_authentication_contexts = ['fedict']
|
||||
fd2 = assert_xml_import_export_works(formdef, include_id=True)
|
||||
assert fd2.required_authentication_contexts == formdef.required_authentication_contexts
|
||||
|
||||
def test_field_condition():
|
||||
formdef = FormDef()
|
||||
formdef.name = 'Foo'
|
||||
formdef.fields = [
|
||||
fields.StringField(type='string', id=1, label='Bar', size='40',
|
||||
condition={'type': 'django', 'value': '1'})
|
||||
]
|
||||
f2 = assert_xml_import_export_works(formdef)
|
||||
assert len(f2.fields) == len(formdef.fields)
|
||||
assert f2.fields[0].condition == {'type': 'django', 'value': '1'}
|
||||
|
|
|
@ -36,6 +36,7 @@ class FieldDefPage(Directory):
|
|||
|
||||
large = False
|
||||
page_id = None
|
||||
blacklisted_attributes = []
|
||||
|
||||
def __init__(self, objectdef, field_id):
|
||||
self.objectdef = objectdef
|
||||
|
@ -52,10 +53,8 @@ class FieldDefPage(Directory):
|
|||
form = Form(enctype='multipart/form-data',
|
||||
advanced_label=_('Additional parameters'))
|
||||
self.field.fill_admin_form(form)
|
||||
#form.add(SingleSelectWidget, 'type', title = _('Type'),
|
||||
# value = self.field.type, required=True,
|
||||
# options = [(x, _(y)) for x,y in get_field_types()])
|
||||
#current_type = form.get_widget('type').parse()
|
||||
form.widgets = [x for x in form.widgets
|
||||
if getattr(x, 'name', None) not in self.blacklisted_attributes]
|
||||
form.add_submit('submit', _('Submit'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
return form
|
||||
|
|
|
@ -105,8 +105,11 @@ authentication is unavailable. Lasso must be installed to use it.'))
|
|||
get_response().breadcrumb.append( ('identification/', _('Identification')) )
|
||||
return qommon.ident.get_method_admin_directory(component)
|
||||
|
||||
|
||||
class UserFieldDefPage(FieldDefPage):
|
||||
section = 'settings'
|
||||
blacklisted_attributes = ['condition']
|
||||
|
||||
|
||||
class UserFieldsDirectory(FieldsDirectory):
|
||||
_q_exports = ['', 'update_order', 'new', 'mapping']
|
||||
|
|
|
@ -822,6 +822,7 @@ class WorkflowVariableWidget(CompositeWidget):
|
|||
|
||||
class WorkflowVariablesFieldDefPage(FieldDefPage):
|
||||
section = 'workflows'
|
||||
blacklisted_attributes = ['condition']
|
||||
|
||||
def form(self):
|
||||
form = super(WorkflowVariablesFieldDefPage, self).form()
|
||||
|
@ -834,6 +835,7 @@ class WorkflowVariablesFieldDefPage(FieldDefPage):
|
|||
|
||||
class WorkflowBackofficeFieldDefPage(FieldDefPage):
|
||||
section = 'workflows'
|
||||
blacklisted_attributes = ['condition']
|
||||
|
||||
def form(self):
|
||||
form = super(WorkflowBackofficeFieldDefPage, self).form()
|
||||
|
@ -870,6 +872,7 @@ class WorkflowBackofficeFieldsDirectory(FieldsDirectory):
|
|||
field_def_page_class = WorkflowBackofficeFieldDefPage
|
||||
support_import = False
|
||||
blacklisted_types = ['page']
|
||||
blacklisted_attributes = ['condition']
|
||||
field_var_prefix = 'form_var_'
|
||||
|
||||
def index_top(self):
|
||||
|
|
|
@ -160,6 +160,7 @@ class Field(object):
|
|||
prefill = None
|
||||
store_display_value = None
|
||||
store_structured_value = None
|
||||
condition = None
|
||||
|
||||
# flag a field for removal by AnonymiseWorkflowStatusItem
|
||||
# can be overriden in field' settings
|
||||
|
@ -181,7 +182,7 @@ class Field(object):
|
|||
re.sub('<.*?>', ' ', self.label), charset)).strip().encode(charset)
|
||||
|
||||
def get_admin_attributes(self):
|
||||
return ['label', 'type']
|
||||
return ['label', 'type', 'condition']
|
||||
|
||||
def export_to_json(self, include_id=False):
|
||||
field = {}
|
||||
|
@ -284,6 +285,18 @@ class Field(object):
|
|||
except:
|
||||
pass
|
||||
|
||||
def condition_init_with_xml(self, node, charset, include_id=False):
|
||||
self.condition = None
|
||||
if node is None:
|
||||
return
|
||||
if node.findall('type'):
|
||||
self.condition = {
|
||||
'type': node.find('type').text.encode(charset),
|
||||
'value': node.find('value').text.encode(charset),
|
||||
}
|
||||
elif node.text:
|
||||
self.condition = {'type': 'python', 'value': node.text.strip().encode(charset)}
|
||||
|
||||
def get_rst_view_value(self, value, indent=''):
|
||||
return indent + self.get_view_value(value)
|
||||
|
||||
|
@ -359,6 +372,15 @@ class Field(object):
|
|||
def migrate(self):
|
||||
return False
|
||||
|
||||
def evaluate_condition(self, dict_vars, formdef, condition):
|
||||
return PageCondition(condition, {'dict_vars': dict_vars, 'formdef': formdef}).evaluate()
|
||||
|
||||
def is_visible(self, dict, formdef):
|
||||
try:
|
||||
return self.evaluate_condition(dict, formdef, self.condition)
|
||||
except RuntimeError:
|
||||
return True
|
||||
|
||||
|
||||
class WidgetField(Field):
|
||||
hint = None
|
||||
|
@ -443,6 +465,9 @@ class WidgetField(Field):
|
|||
form.add(PrefillSelectionWidget, 'prefill', title=_('Prefill'),
|
||||
value=self.prefill, advanced=prefill_in_advanced,
|
||||
field=self)
|
||||
form.add(ConditionWidget, 'condition', title=_('Display Condition'), value=self.condition,
|
||||
required=False, size=50, django_only=True,
|
||||
advanced=not(bool(self.condition)))
|
||||
if 'anonymise' in self.get_admin_attributes():
|
||||
# override anonymise flag default value
|
||||
form.add(CheckboxWidget, 'anonymise', title=_('Anonymise'),
|
||||
|
@ -507,6 +532,9 @@ class TitleField(Field):
|
|||
required = True, size = 50)
|
||||
form.add(StringWidget, 'extra_css_class', title = _('Extra classes for CSS styling'),
|
||||
value=self.extra_css_class, size=30, advanced=(not self.extra_css_class))
|
||||
form.add(ConditionWidget, 'condition', title=_('Display Condition'), value=self.condition,
|
||||
required=False, size=50, django_only=True,
|
||||
advanced=not(bool(self.condition)))
|
||||
|
||||
def get_admin_attributes(self):
|
||||
return Field.get_admin_attributes(self) + ['extra_css_class']
|
||||
|
@ -568,6 +596,9 @@ class CommentField(Field):
|
|||
required=True)
|
||||
form.add(StringWidget, 'extra_css_class', title = _('Extra classes for CSS styling'),
|
||||
value=self.extra_css_class, size=30, advanced=(not self.extra_css_class))
|
||||
form.add(ConditionWidget, 'condition', title=_('Display Condition'), value=self.condition,
|
||||
required=False, size=50, django_only=True,
|
||||
advanced=not(bool(self.condition)))
|
||||
|
||||
def get_admin_attributes(self):
|
||||
return Field.get_admin_attributes(self) + ['extra_css_class']
|
||||
|
@ -1545,21 +1576,8 @@ class PageField(Field):
|
|||
key = 'page'
|
||||
description = N_('Page')
|
||||
|
||||
condition = None
|
||||
post_conditions = None
|
||||
|
||||
def condition_init_with_xml(self, node, charset, include_id=False):
|
||||
self.condition = None
|
||||
if node is None:
|
||||
return
|
||||
if node.findall('type'):
|
||||
self.condition = {
|
||||
'type': node.find('type').text.encode(charset),
|
||||
'value': node.find('value').text.encode(charset),
|
||||
}
|
||||
elif node.text:
|
||||
self.condition = {'type': 'python', 'value': node.text.strip().encode(charset)}
|
||||
|
||||
def post_conditions_init_with_xml(self, node, charset, include_id=False):
|
||||
if node is None:
|
||||
return
|
||||
|
@ -1600,7 +1618,7 @@ class PageField(Field):
|
|||
def fill_admin_form(self, form):
|
||||
form.add(StringWidget, 'label', title = _('Label'), value = self.label,
|
||||
required = True, size = 50)
|
||||
form.add(ConditionWidget, 'condition', title=_('Condition'), value=self.condition,
|
||||
form.add(ConditionWidget, 'condition', title=_('Display Condition'), value=self.condition,
|
||||
required=False, size=50)
|
||||
form.add(PostConditionsTableWidget, 'post_conditions',
|
||||
title=_('Post Conditions'),
|
||||
|
@ -1631,15 +1649,6 @@ class PageField(Field):
|
|||
def add_to_view_form(self, *args):
|
||||
pass
|
||||
|
||||
def evaluate_condition(self, dict_vars, formdef, condition):
|
||||
return PageCondition(condition, {'dict_vars': dict_vars, 'formdef': formdef}).evaluate()
|
||||
|
||||
def is_visible(self, dict, formdef):
|
||||
try:
|
||||
return self.evaluate_condition(dict, formdef, self.condition)
|
||||
except RuntimeError:
|
||||
return True
|
||||
|
||||
register_field_class(PageField)
|
||||
|
||||
|
||||
|
|
|
@ -536,6 +536,8 @@ class FormDef(StorableObject):
|
|||
continue
|
||||
if not on_page:
|
||||
continue
|
||||
if not field.is_visible(form_data, self):
|
||||
continue
|
||||
if type(displayed_fields) is list:
|
||||
displayed_fields.append(field)
|
||||
value = None
|
||||
|
@ -586,6 +588,9 @@ class FormDef(StorableObject):
|
|||
# same text as the page.
|
||||
continue
|
||||
|
||||
if not field.is_visible(dict, self):
|
||||
continue
|
||||
|
||||
value = dict.get(field.id, '')
|
||||
field.add_to_view_form(form, value)
|
||||
|
||||
|
|
|
@ -2359,10 +2359,10 @@ class ConditionWidget(CompositeWidget):
|
|||
if not value:
|
||||
value = {}
|
||||
|
||||
options = [
|
||||
('python', _('Python Expression'), 'python'),
|
||||
('django', _('Django Expression'), 'django'),
|
||||
]
|
||||
options = []
|
||||
if not kwargs.get('django_only'):
|
||||
options.append(('python', _('Python Expression'), 'python'))
|
||||
options.append(('django', _('Django Expression'), 'django'))
|
||||
|
||||
self.add(StringWidget, 'value_django', size=80,
|
||||
value=value.get('value') if value.get('type') == 'django' else None)
|
||||
|
|
|
@ -67,6 +67,7 @@ class WorkflowFormFieldsDirectory(FieldsDirectory):
|
|||
section = 'workflows'
|
||||
support_import = False
|
||||
blacklisted_types = ['page']
|
||||
blacklisted_attributes = ['condition']
|
||||
field_def_page_class = WorkflowFormFieldDefPage
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue