diff --git a/tests/test_widgets.py b/tests/test_widgets.py index c85b67921..b254b1065 100644 --- a/tests/test_widgets.py +++ b/tests/test_widgets.py @@ -906,6 +906,19 @@ def test_wcsextrastringwidget_builtin_validation(): assert widget.error == 'You should enter a 5-digits zip code, for example 75014.' +def test_wcsextrastringwidget_maxlength(): + widget = WcsExtraStringWidget('test', value='foo', required=False, maxlength=10) + mock_form_submission(req, widget, {'test': '123'}) + assert not widget.has_error() + + widget = WcsExtraStringWidget('test', value='foo', required=False, maxlength=10) + mock_form_submission(req, widget, {'test': '1234567890abcdef'}) + assert widget.has_error() + + form = MockHtmlForm(widget) + assert 'maxlength="10"' in form.as_html + + def test_wcsextrastringwidget_phone(): class FakeField: pass diff --git a/wcs/fields/string.py b/wcs/fields/string.py index 5e702ec16..95d53f5f2 100644 --- a/wcs/fields/string.py +++ b/wcs/fields/string.py @@ -45,7 +45,8 @@ class StringField(WidgetField): widget_class = WcsExtraStringWidget size = None - extra_attributes = ['size'] + maxlength = None + extra_attributes = ['size', 'maxlength'] validation = {} data_source = {} keep_raw_value = False @@ -85,6 +86,13 @@ class StringField(WidgetField): value=self.validation, advanced=True, ) + form.add( + StringWidget, + 'maxlength', + title=_('Maximum number of characters'), + value=self.maxlength, + advanced=True, + ) form.add( data_sources.DataSourceSelectionWidget, 'data_source', @@ -97,7 +105,13 @@ class StringField(WidgetField): ) def get_admin_attributes(self): - return WidgetField.get_admin_attributes(self) + ['size', 'validation', 'data_source', 'anonymise'] + return WidgetField.get_admin_attributes(self) + [ + 'size', + 'validation', + 'data_source', + 'anonymise', + 'maxlength', + ] def get_view_value(self, value, **kwargs): value = value or '' diff --git a/wcs/qommon/form.py b/wcs/qommon/form.py index a9fb37ba9..e5a72f9be 100644 --- a/wcs/qommon/form.py +++ b/wcs/qommon/form.py @@ -646,7 +646,7 @@ class StringWidget(QuixoteStringWidget): QuixoteStringWidget._parse(self, request) if self.value: self.value = self.value.strip() - if self.maxlength and len(self.value) > self.maxlength: + if self.maxlength and len(self.value) > int(self.maxlength): self.set_error_code('too_long') elif self.validation_function: try: @@ -655,7 +655,7 @@ class StringWidget(QuixoteStringWidget): self.set_error(str(e)) def get_too_long_message(self): - return _('Too long, value must be at most %d characters.') % self.maxlength + return _('Too long, value must be at most %d characters.') % int(self.maxlength) def get_error_message_codes(self): yield from super().get_error_message_codes()