19
19
from django .core .exceptions import ValidationError # noqa
20
20
from django .core import urlresolvers
21
21
from django .forms import fields
22
+ from django .forms .util import flatatt # noqa
22
23
from django .forms import widgets
23
24
from django .utils .encoding import force_text
24
25
from django .utils .functional import Promise # noqa
@@ -123,7 +124,9 @@ def clean(self, value):
123
124
124
125
class SelectWidget (widgets .Select ):
125
126
"""Customizable select widget, that allows to render
126
- data-xxx attributes from choices.
127
+ data-xxx attributes from choices. This widget also
128
+ allows user to specify additional html attributes
129
+ for choices.
127
130
128
131
.. attribute:: data_attrs
129
132
@@ -137,25 +140,64 @@ class SelectWidget(widgets.Select):
137
140
138
141
A callable used to render the display value
139
142
from the option object.
143
+
144
+ .. attribute:: transform_html_attrs
145
+
146
+ A callable used to render additional HTML attributes
147
+ for the option object. It returns a dictionary
148
+ containing the html attributes and their values.
149
+ For example, to define a title attribute for the
150
+ choices:
151
+
152
+ helpText = { 'Apple': 'This is a fruit',
153
+ 'Carrot': 'This is a vegetable' }
154
+
155
+ def get_title(data):
156
+ text = helpText.get(data, None)
157
+ if text:
158
+ return {'title': text}
159
+ else:
160
+ return {}
161
+
162
+ ....
163
+ ....
164
+
165
+ widget=forms.SelectWidget( attrs={'class': 'switchable',
166
+ 'data-slug': 'source'},
167
+ transform_html_attrs=get_title )
168
+
169
+ self.fields[<field name>].choices =
170
+ ([
171
+ ('apple','Apple'),
172
+ ('carrot','Carrot')
173
+ ])
140
174
"""
141
- def __init__ (self , attrs = None , choices = (), data_attrs = (), transform = None ):
175
+ def __init__ (self , attrs = None , choices = (), data_attrs = (), transform = None ,
176
+ transform_html_attrs = None ):
142
177
self .data_attrs = data_attrs
143
178
self .transform = transform
179
+ self .transform_html_attrs = transform_html_attrs
144
180
super (SelectWidget , self ).__init__ (attrs , choices )
145
181
146
182
def render_option (self , selected_choices , option_value , option_label ):
147
183
option_value = force_text (option_value )
148
184
other_html = (option_value in selected_choices ) and \
149
185
u' selected="selected"' or ''
186
+
187
+ if callable (self .transform_html_attrs ):
188
+ html_attrs = self .transform_html_attrs (option_label )
189
+ other_html += flatatt (html_attrs )
190
+
150
191
if not isinstance (option_label , (basestring , Promise )):
151
192
for data_attr in self .data_attrs :
152
193
data_value = html .conditional_escape (
153
194
force_text (getattr (option_label ,
154
195
data_attr , "" )))
155
196
other_html += ' data-%s="%s"' % (data_attr , data_value )
156
197
157
- if self .transform :
198
+ if callable ( self .transform ) :
158
199
option_label = self .transform (option_label )
200
+
159
201
return u'<option value="%s"%s>%s</option>' % (
160
202
html .escape (option_value ), other_html ,
161
203
html .conditional_escape (force_text (option_label )))
0 commit comments