fields: add min_choices option to ItemsField (#49896)
This commit is contained in:
parent
b918c88f0f
commit
e14acb7d05
|
@ -1679,6 +1679,8 @@ def test_form_edit_items_field(pub):
|
|||
|
||||
resp = resp.click('Edit', href='1/')
|
||||
assert resp.forms[0]['label'].value == '1st field'
|
||||
assert resp.forms[0]['min_choices'].value == '0'
|
||||
assert resp.forms[0]['max_choices'].value == '0'
|
||||
resp.forms[0]['label'] = 'changed field'
|
||||
resp.forms[0]['required'] = False
|
||||
resp = resp.forms[0].submit('items$add_element')
|
||||
|
@ -1691,16 +1693,22 @@ def test_form_edit_items_field(pub):
|
|||
resp = resp.follow()
|
||||
|
||||
assert FormDef.get(1).fields[0].label == 'changed field'
|
||||
assert FormDef.get(1).fields[0].required == False
|
||||
assert FormDef.get(1).fields[0].required is False
|
||||
assert FormDef.get(1).fields[0].items is None
|
||||
assert FormDef.get(1).fields[0].min_choices == 0
|
||||
assert FormDef.get(1).fields[0].max_choices == 0
|
||||
|
||||
# edit and fill with one item
|
||||
resp = resp.click('Edit', href='1/')
|
||||
assert resp.forms[0]['label'].value == 'changed field'
|
||||
resp.forms[0]['items$element0'] = 'XXX'
|
||||
resp.forms[0]['min_choices'] = 2
|
||||
resp.forms[0]['max_choices'] = 5
|
||||
resp = resp.forms[0].submit('submit')
|
||||
assert resp.location == 'http://example.net/backoffice/forms/1/fields/#itemId_1'
|
||||
assert FormDef.get(1).fields[0].items == ['XXX']
|
||||
assert FormDef.get(1).fields[0].min_choices == 2
|
||||
assert FormDef.get(1).fields[0].max_choices == 5
|
||||
|
||||
# check prefilling is only possible with Python
|
||||
resp = resp.follow()
|
||||
|
|
|
@ -526,11 +526,13 @@ def test_form_string_field_submit(pub):
|
|||
|
||||
def test_form_items_submit(pub):
|
||||
formdef = create_formdef()
|
||||
formdef.fields = [fields.ItemsField(id='0', label='items', type='items',
|
||||
required=True,
|
||||
varname='foo', items=['Foo', 'Bar', 'Three']),]
|
||||
formdef.fields = [fields.ItemsField(
|
||||
id='0', label='items', type='items',
|
||||
required=True,
|
||||
varname='foo', items=['Foo', 'Bar', 'Three', 'Four', 'Five', 'Six'])]
|
||||
formdef.store()
|
||||
formdef.data_class().wipe()
|
||||
|
||||
page = get_app(pub).get('/test/')
|
||||
next_page = page.forms[0].submit('submit') # but the field is required
|
||||
assert next_page.pyquery('div.error').text() == 'required field'
|
||||
|
@ -548,6 +550,25 @@ def test_form_items_submit(pub):
|
|||
assert data.data['0'] == ['Foo', 'Bar']
|
||||
assert data.data['0_display'] == 'Foo, Bar'
|
||||
|
||||
formdef.fields[0].min_choices = 2
|
||||
formdef.fields[0].max_choices = 5
|
||||
formdef.store()
|
||||
|
||||
page = get_app(pub).get('/test/')
|
||||
page.forms[0]['f0$element0'].checked = True
|
||||
page = page.forms[0].submit('submit')
|
||||
assert page.pyquery('div.error').text() == 'You must select at least 2 answers.'
|
||||
page.forms[0]['f0$element1'].checked = True
|
||||
page.forms[0]['f0$element2'].checked = True
|
||||
page.forms[0]['f0$element3'].checked = True
|
||||
page.forms[0]['f0$element4'].checked = True
|
||||
page.forms[0]['f0$element5'].checked = True
|
||||
page = page.forms[0].submit('submit')
|
||||
assert page.pyquery('div.error').text() == 'You must select at most 5 answers.'
|
||||
page.forms[0]['f0$element5'].checked = False
|
||||
page = next_page.forms[0].submit('submit').follow()
|
||||
assert 'The form has been recorded' in page.text
|
||||
|
||||
|
||||
def test_form_string_with_invalid_xml_chars(pub):
|
||||
formdef = create_formdef()
|
||||
|
|
|
@ -1791,6 +1791,7 @@ class ItemsField(WidgetField):
|
|||
allow_complex = True
|
||||
|
||||
items = []
|
||||
min_choices = 0
|
||||
max_choices = 0
|
||||
data_source = {}
|
||||
in_filters = False
|
||||
|
@ -1817,6 +1818,7 @@ class ItemsField(WidgetField):
|
|||
|
||||
def perform_more_widget_changes(self, form, kwargs, edit = True):
|
||||
kwargs['options'] = self.get_options()
|
||||
kwargs['min_choices'] = self.min_choices
|
||||
kwargs['max_choices'] = self.max_choices
|
||||
if self.data_source:
|
||||
items = data_sources.get_items(self.data_source,
|
||||
|
@ -1835,6 +1837,8 @@ class ItemsField(WidgetField):
|
|||
value = self.items, required = False,
|
||||
element_kwargs = {'render_br': False, 'size': 50},
|
||||
add_element_label = _('Add item'))
|
||||
form.add(IntWidget, 'min_choices', title=_('Minimum number of choices'),
|
||||
value=self.min_choices, required=False, size=4)
|
||||
form.add(IntWidget, 'max_choices', title = _('Maximum number of choices'),
|
||||
value = self.max_choices, required = False, size = 4)
|
||||
form.add(data_sources.DataSourceSelectionWidget, 'data_source',
|
||||
|
@ -1850,9 +1854,9 @@ class ItemsField(WidgetField):
|
|||
advanced=not(self.display_disabled_items))
|
||||
|
||||
def get_admin_attributes(self):
|
||||
return WidgetField.get_admin_attributes(self) + ['items',
|
||||
'max_choices', 'data_source', 'in_filters', 'anonymise',
|
||||
'display_disabled_items']
|
||||
return WidgetField.get_admin_attributes(self) + [
|
||||
'items', 'min_choices', 'max_choices', 'data_source', 'in_filters', 'anonymise',
|
||||
'display_disabled_items']
|
||||
|
||||
def check_admin_form(self, form):
|
||||
items = form.get_widget('items').parse()
|
||||
|
|
|
@ -1349,6 +1349,7 @@ class CheckboxesWidget(CompositeWidget):
|
|||
del kwargs['readonly']
|
||||
self.readonly = True
|
||||
self.inline = kwargs.get('inline', True)
|
||||
self.min_choices = int(kwargs.get('min_choices', 0) or 0)
|
||||
self.max_choices = int(kwargs.get('max_choices', 0) or 0)
|
||||
|
||||
self.options_with_attributes = kwargs.pop('options_with_attributes', None)
|
||||
|
@ -1393,6 +1394,8 @@ class CheckboxesWidget(CompositeWidget):
|
|||
self.value = values
|
||||
if self.required and not self.value:
|
||||
self.set_error(self.REQUIRED_ERROR)
|
||||
if self.value and self.min_choices and len(self.value) < self.min_choices:
|
||||
self.set_error(_('You must select at least %d answers.') % self.min_choices)
|
||||
if self.value and self.max_choices and len(self.value) > self.max_choices:
|
||||
self.set_error(_('You must select at most %d answers.') % self.max_choices)
|
||||
|
||||
|
|
Loading…
Reference in New Issue