misc: extend custom error messages to all validation types (#63038) #216
|
@ -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)
|
||||
|
|
|
@ -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]]),
|
||||
fpeters
commented
Le code précédent était pour prendre les libellés des options regex et django, le nouveau code est pour prendre tous les identifiants de type de validation, vu qu'on veut désormais le champ de message perso pour tous les types de validation. Le code précédent était pour prendre les libellés des options regex et django, le nouveau code est pour prendre tous les identifiants de type de validation, vu qu'on veut désormais le champ de message perso pour tous les types de validation.
|
||||
},
|
||||
)
|
||||
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)
|
||||
)
|
||||
fpeters
commented
C'est équivalent au |json_script dispo en templatetag, c'est utilisé ensuite pour avoir tous les libellés disponibles dans le javascript. C'est équivalent au |json_script dispo en templatetag, c'est utilisé ensuite pour avoir tous les libellés disponibles dans le javascript.
|
||||
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'):
|
||||
fpeters
commented
Il n'y avait vraiment pas de raison particulière à ne pas retourner le message personnalisé quand pattern n'était pas défini (en tout cas je n'ai rien trouvé qui aurait expliqué ça). Il n'y avait vraiment pas de raison particulière à ne pas retourner le message personnalisé quand pattern n'était pas défini (en tout cas je n'ai rien trouvé qui aurait expliqué ça).
|
||||
return validation.get('error_message')
|
||||
validation_method = cls.validation_methods.get(validation['type'])
|
||||
if validation_method and 'error_message' in validation_method:
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
fpeters
commented
C'est encore un mix avec un peu de jquery, ça reste plus facile. L'objectif ici est de remplir le champ "message personnalisé" avec le message par défaut, et tant que c'est un des messages par défaut, on peut le remplacer, sinon on laisse celui qui aurait été tapé/modifié par l'utilisateur. C'est encore un mix avec un peu de jquery, ça reste plus facile.
L'objectif ici est de remplir le champ "message personnalisé" avec le message par défaut, et tant que c'est un des messages par défaut, on peut le remplacer, sinon on laisse celui qui aurait été tapé/modifié par l'utilisateur.
|
||||
|
||||
function prepate_journal_links() {
|
||||
$('#journal-page-links a').on('click', function() {
|
||||
var url = $(this).attr('href');
|
||||
|
|
C'est ça qui fait les changements dans les tests type
et plus bas