From c659d900b8f968290ffbad0cf84dfdba2a9ffd64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Wed, 10 Oct 2018 09:50:16 +0200 Subject: [PATCH] forms: add support for live list contents (#27173) --- tests/test_form_pages.py | 53 +++++++++++++++++++++++++ tests/utilities.py | 1 + wcs/data_sources.py | 10 ++--- wcs/fields.py | 4 +- wcs/formdef.py | 58 ++++++++++++++++++---------- wcs/forms/root.py | 45 ++++++++++++++++++--- wcs/qommon/static/js/qommon.forms.js | 13 +++++++ wcs/qommon/substitution.py | 9 ++++- 8 files changed, 158 insertions(+), 35 deletions(-) diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py index a1c653696..755b977cd 100644 --- a/tests/test_form_pages.py +++ b/tests/test_form_pages.py @@ -5480,3 +5480,56 @@ def test_field_live_condition_multipages(pub): assert 'name="f2"' in resp.body assert 'name="f4"' in resp.body resp = resp.form.submit('submit') + +def test_field_live_select_content(pub, http_requests): + FormDef.wipe() + formdef = FormDef() + formdef.name = 'Foo' + formdef.fields = [ + fields.StringField(type='string', id='1', label='Bar', size='40', + required=True, varname='bar'), + fields.StringField(type='string', id='2', label='Bar2', size='40', + required=True, varname='bar2'), + fields.ItemField(type='item', id='3', label='Foo', + data_source={ + 'type': 'json', + 'value': '{% if form_var_bar2 %}http://remote.example.net/json-list?plop={{form_var_bar2}}{% endif %}' + }), + ] + formdef.store() + + app = get_app(pub) + resp = app.get('/foo/') + assert 'f1' in resp.form.fields + assert 'f2' in resp.form.fields + assert resp.html.find('div', {'data-field-id': '2'}).attrs['data-live-source'] == 'true' + assert resp.html.find('div', {'data-field-id': '3'}).find('select') + resp.form['f1'] = 'hello' + live_resp = app.post('/foo/live', params=resp.form.submit_fields()) + assert live_resp.json['result']['1']['visible'] + assert live_resp.json['result']['2']['visible'] + assert live_resp.json['result']['3']['visible'] + assert not 'items' in live_resp.json['result']['3'] + resp.form['f2'] = 'plop' + live_resp = app.post('/foo/live?modified_field_id=2', params=resp.form.submit_fields()) + assert live_resp.json['result']['1']['visible'] + assert live_resp.json['result']['2']['visible'] + assert live_resp.json['result']['3']['visible'] + assert 'items' in live_resp.json['result']['3'] + resp.form['f3'].options = [] + for item in live_resp.json['result']['3']['items']: + # simulate javascript filling the contents + var $select = $widget.find('select'); + var current_value = $select.val(); + $select.empty(); + for (var i=0; i', {value: value.items[i].id, text: value.items[i].text}); + if (value.items[i].id == current_value) { + $option.attr('selected', 'selected'); + } + $option.appendTo($select); + } + } }); } }); diff --git a/wcs/qommon/substitution.py b/wcs/qommon/substitution.py index 7441ba0b1..7a1a74b15 100644 --- a/wcs/qommon/substitution.py +++ b/wcs/qommon/substitution.py @@ -32,9 +32,10 @@ def invalidate_substitution_cache(func): class Substitutions(object): substitutions_dict = {} dynamic_sources = [] - sources = None + _forced_mode = None + def __init__(self): self.sources = [] @@ -77,7 +78,7 @@ class Substitutions(object): self.invalidate_cache() @contextmanager - def temporary_feed(self, source): + def temporary_feed(self, source, force_mode=None): if source is None or source in self.sources: yield return @@ -85,7 +86,9 @@ class Substitutions(object): orig_sources, self.sources = self.sources, self.sources[:] self.sources.append(source) self.invalidate_cache() + old_mode, self._forced_mode = self._forced_mode, force_mode yield + self._forced_mode = old_mode self.sources = orig_sources self.invalidate_cache() @@ -95,6 +98,8 @@ class Substitutions(object): delattr(self, '_cache_context_variables%r' % value) def get_context_variables(self, mode=None): + if self._forced_mode: + mode = self._forced_mode lazy = mode in get_publisher().get_lazy_variables_modes() if mode else False d = getattr(self, '_cache_context_variables%r' % lazy, None) if d is not None: -- 2.19.1