misc: extend custom error messages to all validation types (#63038)
gitea/wcs/pipeline/head This commit looks good Details

This commit is contained in:
Frédéric Péters 2023-03-31 14:28:09 +02:00
parent 6d355739c7
commit bd9e89cd6a
3 changed files with 58 additions and 20 deletions

View File

@ -2008,7 +2008,7 @@ def test_form_edit_string_field_validation(pub):
assert '1st field' in resp.text
resp = resp.click('Edit', href='1/')
resp.form['validation$type'] = 'Regular Expression'
resp.form['validation$type'] = 'regex'
resp.form['validation$value_regex'] = r'\d+'
resp.form['validation$error_message'] = 'Foo Error'
resp = resp.form.submit('submit').follow()
@ -2019,12 +2019,12 @@ def test_form_edit_string_field_validation(pub):
}
resp = resp.click('Edit', href='1/')
resp.form['validation$type'] = 'None'
resp.form['validation$type'] = ''
resp = resp.form.submit('submit').follow()
assert FormDef.get(formdef.id).fields[0].validation is None
resp = resp.click('Edit', href='1/')
resp.form['validation$type'] = 'Django Condition'
resp.form['validation$type'] = 'django'
resp.form['validation$value_django'] = 'value|decimal < 20'
resp.form['validation$error_message'] = 'Bar Error'
resp = resp.form.submit('submit').follow()
@ -2035,11 +2035,30 @@ def test_form_edit_string_field_validation(pub):
}
resp = resp.click('Edit', href='1/')
resp.form['validation$type'] = 'Django Condition'
resp.form['validation$type'] = 'django'
resp.form['validation$value_django'] = '{{ value|decimal < 20 }}'
resp = resp.form.submit('submit')
assert 'syntax error' in resp.text
# check default error message is not saved
resp.form['validation$value_django'] = ''
resp.form['validation$type'] = 'time'
resp.form['validation$error_message'] = 'Invalid time'
resp = resp.form.submit('submit').follow()
assert FormDef.get(formdef.id).fields[0].validation == {
'type': 'time',
}
# but custom message is saved
resp = resp.click('Edit', href='1/')
resp.form['validation$type'] = 'time'
resp.form['validation$error_message'] = 'Invalid time, it must be in hh:mm format.'
resp = resp.form.submit('submit')
assert FormDef.get(formdef.id).fields[0].validation == {
'type': 'time',
'error_message': 'Invalid time, it must be in hh:mm format.',
}
def test_form_edit_text_field(pub):
create_superuser(pub)

View File

@ -1218,7 +1218,7 @@ class ValidationWidget(CompositeWidget):
if not value:
value = {}
options = [(None, _('None'))] + [(x, y['title']) for x, y in self.validation_methods.items()]
options = [(None, _('None'), '')] + [(x, y['title'], x) for x, y in self.validation_methods.items()]
self.add(
SingleSelectWidget,
@ -1231,7 +1231,6 @@ class ValidationWidget(CompositeWidget):
if not self.value:
self.value = {}
validation_labels = collections.OrderedDict(options)
self.add(
RegexStringWidget,
'value_regex',
@ -1239,7 +1238,7 @@ class ValidationWidget(CompositeWidget):
value=value.get('value') if value.get('type') == 'regex' else None,
attrs={
'data-dynamic-display-child-of': 'validation$type',
'data-dynamic-display-value': validation_labels.get('regex'),
'data-dynamic-display-value': 'regex',
},
)
self.add(
@ -1249,21 +1248,22 @@ class ValidationWidget(CompositeWidget):
value=value.get('value') if value.get('type') == 'django' else None,
attrs={
'data-dynamic-display-child-of': 'validation$type',
'data-dynamic-display-value': validation_labels.get('django'),
'data-dynamic-display-value': 'django',
},
)
self.add(
StringWidget,
'error_message',
size=80,
value=value.get('error_message') if value.get('type') in ['regex', 'django'] else None,
value=value.get('error_message') if value.get('type') else None,
title=_('Custom error message'),
hint=_('This message will be be displayed if validation fails.'),
hint=_(
'This message will be be displayed if validation fails. '
'An empty value will give the default error message.'
),
attrs={
'data-dynamic-display-child-of': 'validation$type',
'data-dynamic-display-value-in': '|'.join(
[str(validation_labels.get('regex')), str(validation_labels.get('django'))]
),
'data-dynamic-display-value-in': '|'.join([x[2] for x in options if x[2]]),
},
)
self._parsed = False
@ -1276,9 +1276,10 @@ class ValidationWidget(CompositeWidget):
value = self.get('value_%s' % type_)
if value:
values['value'] = value
if type_ in ['regex', 'django']:
error_message = self.get('error_message')
if error_message:
error_message = self.get('error_message')
if error_message:
default_error_message = self.validation_methods[type_].get('error_message')
if error_message != default_error_message:
values['error_message'] = error_message
self.value = values or None
@ -1293,6 +1294,15 @@ class ValidationWidget(CompositeWidget):
r += widget.render_content()
widget = self.get_widget('error_message')
r += widget.render()
error_messages = {
x: str(y.get('error_message'))
for x, y in self.validation_methods.items()
if y.get('error_message')
}
r += htmltext(
'<script id="validation-error-messages" type="application/json">%s</script>'
% json.dumps(error_messages)
)
return r.getvalue()
@classmethod
@ -1317,10 +1327,7 @@ class ValidationWidget(CompositeWidget):
@classmethod
def get_validation_error_message(cls, validation):
pattern = cls.get_validation_pattern(validation)
if validation['type'] == 'regex' and pattern:
return validation.get('error_message')
if validation['type'] == 'django' and validation.get('value'):
if validation.get('error_message'):
return validation.get('error_message')
validation_method = cls.validation_methods.get(validation['type'])
if validation_method and 'error_message' in validation_method:

View File

@ -350,6 +350,18 @@ $(function() {
});
$('[type=radio][name=display_mode]:checked').trigger('change');
if (document.getElementById('validation-error-messages')) {
const error_messages = JSON.parse(document.getElementById('validation-error-messages').textContent);
const error_message_widget = document.getElementById('form_validation__error_message');
$('#form_validation__type').on('change', function() {
var current_message = error_message_widget.value;
var new_message = error_messages[$(this).val()];
if (! current_message || Object.values(error_messages).indexOf(current_message) != -1) {
error_message_widget.value = new_message || '';
}
}).trigger('change');
}
function prepate_journal_links() {
$('#journal-page-links a').on('click', function() {
var url = $(this).attr('href');