misc: do not ignore empty block rows when evaluating live value for js (#81094)
gitea/wcs/pipeline/head Build queued...
Details
gitea/wcs/pipeline/head Build queued...
Details
This commit is contained in:
parent
f1f8b95b9b
commit
cced394fed
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue