From e4cc1efaedd0ae484a49085486fd1cb01de9273c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Tue, 7 Apr 2020 14:15:55 +0200 Subject: [PATCH] forms: keep locked field as readonly on page with errors (#41411) --- tests/test_form_pages.py | 28 ++++++++++++++++++++++++++++ wcs/forms/root.py | 11 +++++++++++ 2 files changed, 39 insertions(+) diff --git a/tests/test_form_pages.py b/tests/test_form_pages.py index ac2cb4d6c..ac95359eb 100644 --- a/tests/test_form_pages.py +++ b/tests/test_form_pages.py @@ -5307,6 +5307,34 @@ def test_form_page_profile_verified_prefill(pub): assert formdatas[0].data['0'] == 'foo@localhost' +def test_form_page_verified_prefill_error_page(pub): + user = create_user(pub) + user.verified_fields = ['email'] + user.store() + formdef = create_formdef() + formdef.data_class().wipe() + formdef.fields = [ + fields.StringField(id='0', label='string', required=False), + fields.StringField(id='1', label='string2', required=True), + ] + formdef.store() + + for prefill_settings in ( + {'type': 'user', 'value': 'email'}, # verified profile + {'type': 'string', 'value': 'foo@localhost', 'locked': True}, # locked value + ): + formdef.fields[0].prefill = prefill_settings + formdef.store() + formdef.data_class().wipe() + resp = login(get_app(pub), username='foo', password='foo').get('/test/') + assert resp.form['f0'].value == 'foo@localhost' + assert 'readonly' in resp.form['f0'].attrs + + resp = resp.form.submit('submit') + assert 'There were errors processing the form' in resp.text + assert 'readonly' in resp.form['f0'].attrs + + def test_form_page_profile_verified_date_prefill(pub): user = create_user(pub) diff --git a/wcs/forms/root.py b/wcs/forms/root.py index 4878e9cf7..7ef036970 100644 --- a/wcs/forms/root.py +++ b/wcs/forms/root.py @@ -406,6 +406,14 @@ class FormPage(Directory, FormTemplateMixin): else: req.form = {} + else: + # not a page change, reset_locked_data() will have been called + # earlier, we use that to set appropriate fields as readonly. + for field in displayed_fields: + if get_request().form.get('__locked_f%s' % field.id): + form.get_widget('f%s' % field.id).readonly = 'readonly' + form.get_widget('f%s' % field.id).attrs['readonly'] = 'readonly' + for field in displayed_fields: if field.prefill: # always set additional attributes as they will be used for @@ -969,6 +977,9 @@ class FormPage(Directory, FormTemplateMixin): # submitted by the browser. v = field.convert_value_to_str(v) get_request().form['f%s' % field.id] = v + # keep track of locked field, this will be used when + # redisplaying the same page in case of errors. + get_request().form['__locked_f%s' % field.id] = True def previous_page(self, page_no, magictoken): session = get_session()