0001-blocks-default_items-configuration-58450.patch
tests/form_pages/test_block.py | ||
---|---|---|
895 | 895 |
assert '>bar2<' in resp |
896 | 896 | |
897 | 897 | |
898 |
def test_block_repeated_with_default(pub): |
|
899 |
FormDef.wipe() |
|
900 |
BlockDef.wipe() |
|
901 | ||
902 |
block = BlockDef() |
|
903 |
block.name = 'foobar' |
|
904 |
block.fields = [ |
|
905 |
fields.StringField(id='123', required=True, label='Test', type='string'), |
|
906 |
fields.StringField(id='234', required=True, label='Test2', type='string'), |
|
907 |
] |
|
908 |
block.store() |
|
909 | ||
910 |
formdef = FormDef() |
|
911 |
formdef.name = 'form title' |
|
912 |
formdef.fields = [ |
|
913 |
fields.PageField(id='0', label='1st page', type='page'), |
|
914 |
fields.BlockField( |
|
915 |
id='1', label='test', type='block:foobar', default_items=2, max_items=3, hint='hintblock' |
|
916 |
), |
|
917 |
fields.PageField(id='2', label='2nd page', type='page'), |
|
918 |
] |
|
919 |
formdef.store() |
|
920 | ||
921 |
app = get_app(pub) |
|
922 |
resp = app.get(formdef.get_url()) |
|
923 |
assert resp.text.count('>Test<') == 2 |
|
924 |
assert resp.text.count('>hintblock<') == 1 |
|
925 |
assert 'wcs-block-add-clicked' not in resp |
|
926 |
assert 'Add another' in resp |
|
927 |
assert resp.html.find('div', {'class': 'list-add'}) |
|
928 |
resp = resp.form.submit('f1$add_element') |
|
929 |
assert resp.text.count('>Test<') == 3 |
|
930 |
assert resp.text.count('>hintblock<') == 1 |
|
931 |
assert resp.pyquery('.list-add').attr['style'] == 'display: none' |
|
932 | ||
933 |
formdef.fields[1].default_items = 3 |
|
934 |
formdef.store() |
|
935 | ||
936 |
app = get_app(pub) |
|
937 |
resp = app.get(formdef.get_url()) |
|
938 |
assert resp.text.count('>Test<') == 3 |
|
939 |
assert resp.text.count('>hintblock<') == 1 |
|
940 |
assert resp.pyquery('.list-add').attr['style'] == 'display: none' |
|
941 | ||
942 |
formdef.fields[1].default_items = 4 |
|
943 |
formdef.store() |
|
944 |
app = get_app(pub) |
|
945 |
resp = app.get(formdef.get_url()) |
|
946 |
assert resp.text.count('>Test<') == 3 |
|
947 | ||
948 | ||
898 | 949 |
def test_block_repeated_over_limit(pub): |
899 | 950 |
FormDef.wipe() |
900 | 951 |
BlockDef.wipe() |
... | ... | |
943 | 994 |
assert 'Too many elements (maximum: 2)' in resp |
944 | 995 | |
945 | 996 | |
997 |
def test_block_repeated_under_default(pub): |
|
998 |
FormDef.wipe() |
|
999 |
BlockDef.wipe() |
|
1000 | ||
1001 |
block = BlockDef() |
|
1002 |
block.name = 'foobar' |
|
1003 |
block.fields = [ |
|
1004 |
fields.StringField(id='123', required=True, label='Test', type='string'), |
|
1005 |
fields.StringField(id='234', required=True, label='Test2', type='string'), |
|
1006 |
] |
|
1007 |
block.store() |
|
1008 | ||
1009 |
formdef = FormDef() |
|
1010 |
formdef.name = 'form title' |
|
1011 |
formdef.fields = [ |
|
1012 |
fields.PageField(id='0', label='1st page', type='page'), |
|
1013 |
fields.BlockField( |
|
1014 |
id='1', label='test', type='block:foobar', default_items=2, max_items=2, remove_button=True |
|
1015 |
), |
|
1016 |
fields.PageField(id='2', label='2nd page', type='page'), |
|
1017 |
] |
|
1018 |
formdef.store() |
|
1019 | ||
1020 |
app = get_app(pub) |
|
1021 |
resp = app.get(formdef.get_url()) |
|
1022 |
assert resp.text.count('>Test<') == 2 |
|
1023 | ||
1024 |
# fill items |
|
1025 |
resp.form['f1$element0$f123'] = 'foo1' |
|
1026 |
resp.form['f1$element0$f234'] = 'bar1' |
|
1027 |
resp.form['f1$element1$f123'] = 'foo2' |
|
1028 |
resp.form['f1$element1$f234'] = 'bar2' |
|
1029 | ||
1030 |
resp = resp.form.submit('submit') # -> 2nd page |
|
1031 |
resp = resp.form.submit('submit') # -> validation page |
|
1032 |
assert 'Check values then click submit.' in resp.text |
|
1033 |
assert resp.form['f1$element0$f123'].value == 'foo1' |
|
1034 |
assert resp.form['f1$element0$f234'].value == 'bar1' |
|
1035 |
assert resp.form['f1$element1$f123'].value == 'foo2' |
|
1036 |
assert resp.form['f1$element1$f234'].value == 'bar2' |
|
1037 | ||
1038 |
resp = resp.form.submit('previous') # -> 2nd page |
|
1039 |
resp = resp.form.submit('previous') # -> 1st page |
|
1040 |
# simulate javascript removing of block elements from DOM |
|
1041 |
resp.form.field_order.remove(('f1$element0$f123', resp.form.fields['f1$element0$f123'][0])) |
|
1042 |
del resp.form.fields['f1$element0$f123'] |
|
1043 |
resp.form.field_order.remove(('f1$element0$f234', resp.form.fields['f1$element0$f234'][0])) |
|
1044 |
del resp.form.fields['f1$element0$f234'] |
|
1045 | ||
1046 |
resp = resp.form.submit('submit') # -> 2nd page |
|
1047 |
resp = resp.form.submit('previous') # -> 1st page |
|
1048 |
assert resp.form['f1$element0$f123'].value == 'foo2' |
|
1049 |
assert resp.form['f1$element0$f234'].value == 'bar2' |
|
1050 |
assert 'f1$element1$f123' not in resp.form.fields |
|
1051 |
assert 'f1$element1$f234' not in resp.form.fields |
|
1052 | ||
1053 |
resp = resp.form.submit('submit') # -> 2nd page |
|
1054 |
resp = resp.form.submit('submit') # -> validation page |
|
1055 |
assert resp.form['f1$element0$f123'].value == 'foo2' |
|
1056 |
assert resp.form['f1$element0$f234'].value == 'bar2' |
|
1057 |
assert 'f1$element1$f123' not in resp.form.fields |
|
1058 |
assert 'f1$element1$f234' not in resp.form.fields |
|
1059 | ||
1060 |
resp = resp.form.submit('submit') # -> submit |
|
1061 |
assert len(formdef.data_class().select()[0].data['1']['data']) == 1 |
|
1062 | ||
1063 | ||
946 | 1064 |
def test_block_repeated_files(pub): |
947 | 1065 |
FormDef.wipe() |
948 | 1066 |
BlockDef.wipe() |
wcs/blocks.py | ||
---|---|---|
245 | 245 |
always_include_add_button = True |
246 | 246 | |
247 | 247 |
def __init__( |
248 |
self, name, value=None, title=None, block=None, max_items=None, add_element_label=None, **kwargs |
|
248 |
self, |
|
249 |
name, |
|
250 |
value=None, |
|
251 |
title=None, |
|
252 |
block=None, |
|
253 |
default_items=None, |
|
254 |
max_items=None, |
|
255 |
add_element_label=None, |
|
256 |
**kwargs, |
|
249 | 257 |
): |
250 | 258 |
self.block = block |
251 | 259 |
self.readonly = kwargs.get('readonly') |
... | ... | |
254 | 262 |
element_values = None |
255 | 263 |
if value: |
256 | 264 |
element_values = value.get('data') |
257 |
if not max_items:
|
|
258 |
max_items = 1
|
|
265 |
max_items = max_items or 1
|
|
266 |
default_items = min(default_items or 1, max_items)
|
|
259 | 267 |
hint = kwargs.pop('hint', None) |
260 | 268 |
element_kwargs = {'block': self.block, 'render_br': False, 'remove_button': self.remove_button} |
261 | 269 |
element_kwargs.update(kwargs) |
... | ... | |
263 | 271 |
name, |
264 | 272 |
value=element_values, |
265 | 273 |
title=title, |
274 |
default_items=default_items, |
|
266 | 275 |
max_items=max_items, |
267 | 276 |
element_type=BlockSubWidget, |
268 | 277 |
element_kwargs=element_kwargs, |
wcs/fields.py | ||
---|---|---|
3323 | 3323 |
allow_complex = True |
3324 | 3324 | |
3325 | 3325 |
widget_class = BlockWidget |
3326 |
default_items = 1 |
|
3326 | 3327 |
max_items = 1 |
3327 |
extra_attributes = ['block', 'max_items', 'add_element_label', 'label_display', 'remove_button'] |
|
3328 |
extra_attributes = [ |
|
3329 |
'block', |
|
3330 |
'default_items', |
|
3331 |
'max_items', |
|
3332 |
'add_element_label', |
|
3333 |
'label_display', |
|
3334 |
'remove_button', |
|
3335 |
] |
|
3328 | 3336 |
add_element_label = '' |
3329 | 3337 |
label_display = 'normal' |
3330 | 3338 |
remove_button = False |
... | ... | |
3346 | 3354 |
super().fill_admin_form(form) |
3347 | 3355 |
if form.get_widget('prefill'): |
3348 | 3356 |
form.remove('prefill') |
3357 |
form.add( |
|
3358 |
IntWidget, |
|
3359 |
'default_items', |
|
3360 |
title=_('Number of items to display by default'), |
|
3361 |
value=self.default_items, |
|
3362 |
) |
|
3349 | 3363 |
form.add(IntWidget, 'max_items', title=_('Maximum number of items'), value=self.max_items) |
3350 | 3364 |
form.add( |
3351 | 3365 |
StringWidget, 'add_element_label', title=_('Label of "Add" button'), value=self.add_element_label |
... | ... | |
3366 | 3380 | |
3367 | 3381 |
def get_admin_attributes(self): |
3368 | 3382 |
return super().get_admin_attributes() + [ |
3383 |
'default_items', |
|
3369 | 3384 |
'max_items', |
3370 | 3385 |
'add_element_label', |
3371 | 3386 |
'label_display', |
wcs/qommon/form.py | ||
---|---|---|
1682 | 1682 |
element_type=StringWidget, |
1683 | 1683 |
element_kwargs=None, |
1684 | 1684 |
add_element_label="Add row", |
1685 |
default_items=None, |
|
1685 | 1686 |
max_items=None, |
1686 | 1687 |
**kwargs, |
1687 | 1688 |
): |
... | ... | |
1695 | 1696 |
self.element_type = element_type |
1696 | 1697 |
self.element_kwargs = element_kwargs or {} |
1697 | 1698 |
self.element_names = [] |
1699 |
self.default_items = default_items or 1 |
|
1698 | 1700 |
self.max_items = max_items |
1699 | 1701 | |
1700 | 1702 |
# Add element widgets for initial value |
... | ... | |
1705 | 1707 |
# Add at least an element widget |
1706 | 1708 |
self.add_element() |
1707 | 1709 | |
1710 |
# Add elements until default_items, but only if form was not submitted |
|
1711 |
if not get_request().form: |
|
1712 |
while len(self.element_names) < self.default_items: |
|
1713 |
self.add_element() |
|
1714 | ||
1708 | 1715 |
if not kwargs.get('readonly'): |
1709 | 1716 |
# add element widgets to match submitted list |
1710 | 1717 |
prefix = '%s$element' % self.name |
... | ... | |
1728 | 1735 |
if self.get('add_element') and (not max_items or current_len < max_items): |
1729 | 1736 |
# add an empty row |
1730 | 1737 |
self.add_element() |
1738 |
print(len(self.element_names)) |
|
1731 | 1739 | |
1732 | 1740 |
def add_element(self, value=None, element_name=None): |
1733 | 1741 |
if element_name: |
... | ... | |
1750 | 1758 |
self.set_error(_('Too many elements (maximum: %s)') % self.max_items) |
1751 | 1759 | |
1752 | 1760 |
def set_value(self, value): |
1761 |
print('foobar', value) |
|
1753 | 1762 |
for dummy in range(len(value) - len(self.element_names)): |
1754 | 1763 |
self.add_element() |
1755 | 1764 |
for element_name, subvalue in zip(self.element_names, value): |
1756 |
- |