Code

Ticket #5851: 5851.diff

File 5851.diff, 4.7 KB (added by koenb, 2 years ago)

patch allow list of attrs into multiwidget

Line 
1diff --git a/django/forms/widgets.py b/django/forms/widgets.py
2index 1fbef98..910916b 100644
3--- a/django/forms/widgets.py
4+++ b/django/forms/widgets.py
5@@ -795,7 +795,10 @@ class MultiWidget(Widget):
6     """
7     def __init__(self, widgets, attrs=None):
8         self.widgets = [isinstance(w, type) and w() or w for w in widgets]
9-        super(MultiWidget, self).__init__(attrs)
10+        if attrs is not None:
11+            self.attrs = copy.deepcopy(attrs)
12+        else:
13+            self.attrs = {}
14 
15     def render(self, name, value, attrs=None):
16         if self.is_localized:
17@@ -806,13 +809,27 @@ class MultiWidget(Widget):
18         if not isinstance(value, list):
19             value = self.decompress(value)
20         output = []
21-        final_attrs = self.build_attrs(attrs)
22-        id_ = final_attrs.get('id', None)
23         for i, widget in enumerate(self.widgets):
24             try:
25                 widget_value = value[i]
26             except IndexError:
27                 widget_value = None
28+            if isinstance(self.attrs, list):
29+                try:
30+                    final_attrs= dict(self.attrs[i])
31+                except IndexError:
32+                    final_attrs = {}
33+            else:
34+                final_attrs = dict(self.attrs)
35+            if attrs is not None:
36+                if isinstance(attrs, list):
37+                    try:
38+                        final_attrs.update(attrs[i])
39+                    except IndexError:
40+                        pass
41+                else:
42+                    final_attrs.update(attrs)
43+            id_ = final_attrs.get('id', None)
44             if id_:
45                 final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
46             output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
47@@ -875,8 +892,8 @@ class SplitDateTimeWidget(MultiWidget):
48     """
49 
50     def __init__(self, attrs=None, date_format=None, time_format=None):
51-        widgets = (DateInput(attrs=attrs, format=date_format),
52-                   TimeInput(attrs=attrs, format=time_format))
53+        widgets = (DateInput(format=date_format),
54+                   TimeInput(format=time_format))
55         super(SplitDateTimeWidget, self).__init__(widgets, attrs)
56 
57     def decompress(self, value):
58diff --git a/tests/regressiontests/forms/tests/widgets.py b/tests/regressiontests/forms/tests/widgets.py
59index 2499b7a..edeccad 100644
60--- a/tests/regressiontests/forms/tests/widgets.py
61+++ b/tests/regressiontests/forms/tests/widgets.py
62@@ -870,6 +870,14 @@ beatle J R Ringo False""")
63         w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})), attrs={'id': 'bar'})
64         self.assertHTMLEqual(w.render('name', ['john', 'lennon']), u'<input id="bar_0" type="text" class="big" value="john" name="name_0" /><br /><input id="bar_1" type="text" class="small" value="lennon" name="name_1" />')
65 
66+        # test passing list of attrs, each widget gets the right attrs
67+        w = MyMultiWidget(widgets=(TextInput, TextInput),attrs=[{'class': 'big'}, {'class': 'small'}])
68+        self.assertHTMLEqual(w.render('name', ['john', 'lennon']), u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" class="small" value="lennon" name="name_1" />')
69+
70+        # test incomplete list of attrs
71+        w = MyMultiWidget(widgets=(TextInput, TextInput),attrs=[{'class': 'big'},])
72+        self.assertHTMLEqual(w.render('name', ['john', 'lennon']), u'<input type="text" class="big" value="john" name="name_0" /><br /><input type="text" value="lennon" name="name_1" />')
73+
74         w = MyMultiWidget(widgets=(TextInput(), TextInput()))
75 
76         # test with no initial data
77@@ -896,6 +904,10 @@ beatle J R Ringo False""")
78         w = SplitDateTimeWidget(attrs={'class': 'pretty'})
79         self.assertHTMLEqual(w.render('date', datetime.datetime(2006, 1, 10, 7, 30)), u'<input type="text" class="pretty" value="2006-01-10" name="date_0" /><input type="text" class="pretty" value="07:30:00" name="date_1" />')
80 
81+        # different attrs for the subwidgets
82+        w = SplitDateTimeWidget(attrs=[{'class': 'pretty'}, {'class': 'ugly'}])
83+        self.assertHTMLEqual(w.render('date', datetime.datetime(2006, 1, 10, 7, 30)), u'<input type="text" class="pretty" value="2006-01-10" name="date_0" /><input type="text" class="ugly" value="07:30:00" name="date_1" />')
84+
85         # Use 'date_format' and 'time_format' to change the way a value is displayed.
86         w = SplitDateTimeWidget(date_format='%d/%m/%Y', time_format='%H:%M')
87         self.assertHTMLEqual(w.render('date', datetime.datetime(2006, 1, 10, 7, 30)), u'<input type="text" name="date_0" value="10/01/2006" /><input type="text" name="date_1" value="07:30" />')