From 2a0b9cc5bf6d5ecd44f2288d3d4002305b37a630 Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Thu, 27 Jun 2024 09:56:36 +0200 Subject: [PATCH 1/2] Fix typo in docstring --- src/django_bootstrap5/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/django_bootstrap5/widgets.py b/src/django_bootstrap5/widgets.py index d8bd8f85..ca3f4d9c 100644 --- a/src/django_bootstrap5/widgets.py +++ b/src/django_bootstrap5/widgets.py @@ -8,7 +8,7 @@ class RadioSelectButtonGroup(RadioSelect): - """A RadioSelect that renders as a horizontal button groep.""" + """A RadioSelect that renders as a horizontal button group.""" template_name = "django_bootstrap5/widgets/radio_select_button_group.html" From 8d78e72cf3d9226e6ce2a3119fe11d44c1b00246 Mon Sep 17 00:00:00 2001 From: Xavier Fernandez Date: Thu, 27 Jun 2024 10:54:59 +0200 Subject: [PATCH 2/2] radio_select: allow to disable a single option --- .../widgets/radio_select.html | 2 +- .../widgets/radio_select_button_group.html | 2 +- tests/test_bootstrap_field_radio_select.py | 46 +++++++++++++++++++ ...otstrap_field_radio_select_button_group.py | 45 ++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/django_bootstrap5/templates/django_bootstrap5/widgets/radio_select.html b/src/django_bootstrap5/templates/django_bootstrap5/widgets/radio_select.html index a6441a56..cd45e8ab 100644 --- a/src/django_bootstrap5/templates/django_bootstrap5/widgets/radio_select.html +++ b/src/django_bootstrap5/templates/django_bootstrap5/widgets/radio_select.html @@ -12,7 +12,7 @@ id="{{ option.attrs.id }}" {% if option.value != None %} value="{{ option.value|stringformat:'s' }}" {% if option.attrs.checked %} checked="checked"{% endif %}{% endif %} - {% if widget.attrs.disabled %} disabled{% endif %}> + {% if widget.attrs.disabled or option.attrs.disabled %} disabled{% endif %}> {% endfor %} diff --git a/src/django_bootstrap5/templates/django_bootstrap5/widgets/radio_select_button_group.html b/src/django_bootstrap5/templates/django_bootstrap5/widgets/radio_select_button_group.html index 625d093c..df18fc12 100644 --- a/src/django_bootstrap5/templates/django_bootstrap5/widgets/radio_select_button_group.html +++ b/src/django_bootstrap5/templates/django_bootstrap5/widgets/radio_select_button_group.html @@ -8,7 +8,7 @@ id="{{ option.attrs.id }}" {% if option.value != None %} value="{{ option.value|stringformat:'s' }}" {% if option.attrs.checked %} checked="checked"{% endif %}{% endif %} - {% if widget.attrs.disabled %} disabled{% endif %} + {% if widget.attrs.disabled or option.attrs.disabled %} disabled{% endif %} {% if widget.required %} required{% endif %}> {% endfor %} diff --git a/tests/test_bootstrap_field_radio_select.py b/tests/test_bootstrap_field_radio_select.py index dc1b0a86..3e28f380 100644 --- a/tests/test_bootstrap_field_radio_select.py +++ b/tests/test_bootstrap_field_radio_select.py @@ -24,6 +24,31 @@ class DisabledSelectTestForm(forms.Form): ) +class RadioSelectWithDisabledOptions(forms.RadioSelect): + + def __init__(self, attrs=None, choices=(), *, disabled_values=()): + super().__init__(attrs) + self.choices = choices + self.disabled_values = set(disabled_values) + + def create_option(self, name, value, *args, **kwargs): + option = super().create_option(name, value, *args, **kwargs) + if value in self.disabled_values: + option["attrs"]["disabled"] = True + return option + + +class DisabledOptionSelectTestForm(forms.Form): + test = forms.ChoiceField( + choices=( + (1, "one"), + (2, "two"), + ), + widget=RadioSelectWithDisabledOptions(disabled_values={1}), + ) + + + class BootstrapFieldSelectTestCase(BootstrapTestCase): def test_select(self): """Test field with select widget.""" @@ -111,3 +136,24 @@ def test_disabled_select(self): "" ), ) + + def test_single_disabled_option(self): + """Test field with a disabled option.""" + self.assertHTMLEqual( + self.render("{% bootstrap_field form.test %}", context={"form": DisabledOptionSelectTestForm()}), + ( + '
' + '' + '
' + '
' + '' + '' + "
" + '
' + '' + '' + "
" + "
" + "
" + ), + ) diff --git a/tests/test_bootstrap_field_radio_select_button_group.py b/tests/test_bootstrap_field_radio_select_button_group.py index 2fbd9c48..10ec8e6e 100644 --- a/tests/test_bootstrap_field_radio_select_button_group.py +++ b/tests/test_bootstrap_field_radio_select_button_group.py @@ -26,6 +26,32 @@ class DisabledSelectTestForm(forms.Form): ) +class RadioSelectButtonGroupWithDisabledOptions(RadioSelectButtonGroup): + + def __init__(self, attrs=None, choices=(), *, disabled_values=()): + super().__init__(attrs) + self.choices = choices + self.disabled_values = set(disabled_values) + + def create_option(self, name, value, *args, **kwargs): + option = super().create_option(name, value, *args, **kwargs) + if value in self.disabled_values: + option["attrs"]["disabled"] = True + return option + + +class DisabledOptionSelectTestForm(forms.Form): + test = forms.ChoiceField( + choices=( + (1, "one"), + (2, "two"), + ), + widget=RadioSelectButtonGroupWithDisabledOptions(disabled_values={1}), + ) + + + + class BootstrapFieldSelectTestCase(BootstrapTestCase): def test_select(self): """Test field with select widget.""" @@ -105,3 +131,22 @@ def test_disabled_select(self): "" ), ) + + def test_single_disabled_option(self): + """Test field with a disabled option.""" + self.assertHTMLEqual( + self.render("{% bootstrap_field form.test %}", context={"form": DisabledOptionSelectTestForm()}), + ( + '
' + '' + '
' + '" + '' + '" + '' + "
" + "
" + ), + )