Skip to content

Commit 5059b17

Browse files
committed
creating support for BoundWidget based of jazzband#122 with tests
1 parent 84db553 commit 5059b17

File tree

5 files changed

+53
-5
lines changed

5 files changed

+53
-5
lines changed

.vscode/settings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"python.testing.unittestArgs": [
3+
"-v",
4+
"-s",
5+
"./tests",
6+
"-p",
7+
"*test*.py"
8+
],
9+
"python.testing.pytestEnabled": false,
10+
"python.testing.unittestEnabled": true
11+
}

README.rst

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,22 @@ Output:
268268
<input id="id_name" type="text" name="name" maxlength="100" />
269269
</div>
270270

271+
Fields with multiple widgets
272+
============================
273+
274+
Some fields may render as a `MultiWidget`, composed of multiple subwidgets
275+
(for example, a `ChoiceField` using `RadioSelect`). You can use the same tags
276+
and filters, but your template code will need to include a for loop for fields
277+
like this:
278+
279+
.. code-block:: html+django
280+
281+
{% load widget_tweaks %}
282+
283+
{% for widget in form.choice %}
284+
{{ widget|add_class:"css_class_1 css_class_2" }}
285+
{% endfor %}
286+
271287
Mixing render_field and filters
272288
===============================
273289

@@ -419,8 +435,3 @@ Make sure you have `tox <http://tox.testrun.org/>`_ installed, then type
419435
tox
420436

421437
from the source checkout.
422-
423-
NOT SUPPORTED
424-
=============
425-
426-
MultiWidgets: SplitDateTimeWidget, SplitHiddenDateTimeWidget

tests/forms.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class MyForm(Form):
1515
with_attrs = CharField(widget=TextInput(attrs={"foo": "baz", "egg": "spam"}))
1616
with_cls = CharField(widget=TextInput(attrs={"class": "class0"}))
1717
date = forms.DateField(widget=SelectDateWidget(attrs={"egg": "spam"}))
18+
choice = forms.ChoiceField(choices=[(1, "one"), (2, "two")])
1819

1920

2021
def render_form(text, form=None, **context_args):

tests/tests.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,3 +389,14 @@ def test_field_arroba_dot(self):
389389
def test_field_double_colon_missing(self):
390390
res = render_form('{{ form.simple|attr:"::class:{active:True}" }}')
391391
assertIn(':class="{active:True}"', res)
392+
393+
394+
class ChoiceFieldTest(TestCase):
395+
def test_choice(self):
396+
res = render_field("choice", "attr", "foo:bar")
397+
assertIn("select", res)
398+
assertIn('name="choice"', res)
399+
assertIn('id="id_choice"', res)
400+
assertIn('foo="bar"', res)
401+
assertIn('<option value="1">one</option>', res)
402+
assertIn('<option value="2">two</option>', res)

widget_tweaks/templatetags/widget_tweaks.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@ def _process_field_attributes(field, attr, process):
2424
attribute = params[0].replace("::", ":")
2525
value = params[1] if len(params) == 2 else True
2626
field = copy(field)
27+
28+
if not hasattr(field, "as_widget"):
29+
old_tag = field.tag
30+
31+
def tag(self): # pylint: disable=unused-argument
32+
attrs = self.data["attrs"]
33+
process(self.parent_widget, attrs, attribute, value)
34+
html = old_tag()
35+
self.tag = old_tag
36+
return html
37+
38+
field.tag = types.MethodType(tag, field)
39+
return field
40+
2741
# decorate field.as_widget method with updated attributes
2842
old_as_widget = field.as_widget
2943

0 commit comments

Comments
 (0)