misc: do not ignore empty block rows when evaluating live value for js (#81094)
gitea/wcs/pipeline/head Build queued... Details

This commit is contained in:
Frédéric Péters 2023-09-29 19:43:39 +02:00
parent f1f8b95b9b
commit cced394fed
4 changed files with 73 additions and 2 deletions

View File

@ -2100,6 +2100,61 @@ def test_block_with_block_item_field_condition_and_prefill(pub):
assert resp.form['f1$element0$f234'].value == 'Bar'
def test_block_with_block_empty_row_and_condition(pub):
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.StringField(id='123', required=True, label='One', varname='one'),
fields.StringField(
id='234',
required=True,
label='Two',
condition={'type': 'django', 'value': 'block_var_one'},
),
]
block.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.BlockField(id='1', label='test', block_slug='foobar', max_items=3),
]
formdef.store()
formdef.data_class().wipe()
app = get_app(pub)
resp = app.get(formdef.get_url())
resp.form['f1$element0$f123'] = 'foo'
resp = resp.form.submit('f1$add_element')
resp.form['f1$element1$f123'] = 'bar'
resp = resp.form.submit('f1$add_element')
resp.form['f1$element1$f123'] = ''
resp.form['f1$element2$f123'] = 'baz'
live_resp = app.post(
formdef.get_url() + 'live',
params=resp.form.submit_fields(),
)
assert live_resp.json['result']['1-234-0']['visible'] is True
assert live_resp.json['result']['1-234-1']['visible'] is False
assert live_resp.json['result']['1-234-2']['visible'] is True
resp.form['f1$element0$f234'] = 'foo2'
resp.form['f1$element2$f234'] = 'baz2'
resp = resp.form.submit('submit') # validation
resp = resp.form.submit('submit') # -> end page
formdata = formdef.data_class().select()[0]
assert formdata.data == {
'1': {
'data': [{'123': 'foo', '234': 'foo2'}, {'123': 'baz', '234': 'baz2'}],
'schema': {'123': 'string', '234': 'string'},
},
'1_display': 'foobar, foobar',
}
def test_formdata_page_with_block_bad_value(pub):
BlockDef.wipe()
user = create_user(pub)

View File

@ -417,7 +417,7 @@ class BlockSubWidget(CompositeWidget):
all_lists = False
if widget_value.get(widget.field.id) not in empty_values:
empty = False
if empty and not all_lists:
if empty and not all_lists and not get_publisher().keep_all_block_rows_mode:
value = None
self.value = value

View File

@ -1686,7 +1686,10 @@ class FormPage(Directory, TempfileDirectoryMixin, FormTemplateMixin):
formdata = self.get_transient_formdata()
get_publisher().substitutions.feed(formdata)
displayed_fields = []
with get_publisher().substitutions.temporary_feed(formdata, force_mode='lazy'):
with (
get_publisher().substitutions.temporary_feed(formdata, force_mode='lazy'),
get_publisher().keep_all_block_rows(),
):
form = self.create_form(page=page, displayed_fields=displayed_fields, transient_formdata=formdata)
try:
formdata.data.update(self.formdef.get_data(form, raise_on_error=True))

View File

@ -635,6 +635,19 @@ class WcsPublisher(QommonPublisher):
finally:
self.inspect_recurse_skip_prefixes = None
# when parsing block widgets we usually want to skip empty rows, however
# when evaluating live conditions we must keep all lines to get row indices
# matching what's in the DOM.
keep_all_block_rows_mode = False
@contextmanager
def keep_all_block_rows(self):
self.keep_all_block_rows_mode = True
try:
yield True
finally:
self.keep_all_block_rows_mode = False
def clean_deleted_users(self, **kwargs):
for user_id in self.user_class.get_to_delete_ids():
self.user_class.remove_object(user_id)