Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Document and test 'type' usage in Widget attrs

Refs #16630.
  • Loading branch information...
commit f1bdfbd24bcc76d21c4bf7442959bdf630ac4dec 1 parent 611a2b2
Claude Paroz authored September 10, 2012
2  django/forms/fields.py
@@ -199,7 +199,7 @@ def to_python(self, value):
199 199
 
200 200
     def widget_attrs(self, widget):
201 201
         attrs = super(CharField, self).widget_attrs(widget)
202  
-        if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)):
  202
+        if self.max_length is not None and isinstance(widget, TextInput):
203 203
             # The HTML attribute is maxlength, not max_length.
204 204
             attrs.update({'maxlength': str(self.max_length)})
205 205
         return attrs
18  django/forms/widgets.py
@@ -260,10 +260,17 @@ def render(self, name, value, attrs=None):
260 260
             final_attrs['value'] = force_text(self._format_value(value))
261 261
         return format_html('<input{0} />', flatatt(final_attrs))
262 262
 
  263
+
263 264
 class TextInput(Input):
264 265
     input_type = 'text'
265 266
 
266  
-class PasswordInput(Input):
  267
+    def __init__(self, attrs=None):
  268
+        if attrs is not None:
  269
+            self.input_type = attrs.pop('type', self.input_type)
  270
+        super(TextInput, self).__init__(attrs)
  271
+
  272
+
  273
+class PasswordInput(TextInput):
267 274
     input_type = 'password'
268 275
 
269 276
     def __init__(self, attrs=None, render_value=False):
@@ -400,9 +407,8 @@ def render(self, name, value, attrs=None):
400 407
                            flatatt(final_attrs),
401 408
                            force_text(value))
402 409
 
403  
-class DateInput(Input):
404  
-    input_type = 'text'
405 410
 
  411
+class DateInput(TextInput):
406 412
     def __init__(self, attrs=None, format=None):
407 413
         super(DateInput, self).__init__(attrs)
408 414
         if format:
@@ -431,9 +437,8 @@ def _has_changed(self, initial, data):
431 437
             pass
432 438
         return super(DateInput, self)._has_changed(self._format_value(initial), data)
433 439
 
434  
-class DateTimeInput(Input):
435  
-    input_type = 'text'
436 440
 
  441
+class DateTimeInput(TextInput):
437 442
     def __init__(self, attrs=None, format=None):
438 443
         super(DateTimeInput, self).__init__(attrs)
439 444
         if format:
@@ -462,9 +467,8 @@ def _has_changed(self, initial, data):
462 467
             pass
463 468
         return super(DateTimeInput, self)._has_changed(self._format_value(initial), data)
464 469
 
465  
-class TimeInput(Input):
466  
-    input_type = 'text'
467 470
 
  471
+class TimeInput(TextInput):
468 472
     def __init__(self, attrs=None, format=None):
469 473
         super(TimeInput, self).__init__(attrs)
470 474
         if format:
11  docs/ref/forms/widgets.txt
@@ -126,8 +126,9 @@ provided for each widget will be rendered exactly the same::
126 126
 
127 127
 On a real Web page, you probably don't want every widget to look the same. You
128 128
 might want a larger input element for the comment, and you might want the
129  
-'name' widget to have some special CSS class. To do this, you use the
130  
-:attr:`Widget.attrs` argument when creating the widget:
  129
+'name' widget to have some special CSS class. It is also possible to specify
  130
+the 'type' attribute to take advantage of the new HTML5 input types.  To do
  131
+this, you use the :attr:`Widget.attrs` argument when creating the widget:
131 132
 
132 133
 For example::
133 134
 
@@ -245,7 +246,7 @@ commonly used groups of widgets:
245 246
 
246 247
     Date input as a simple text box: ``<input type='text' ...>``
247 248
 
248  
-    Takes one optional argument:
  249
+    Takes same arguments as :class:`TextInput`, with one more optional argument:
249 250
 
250 251
     .. attribute:: DateInput.format
251 252
 
@@ -262,7 +263,7 @@ commonly used groups of widgets:
262 263
 
263 264
     Date/time input as a simple text box: ``<input type='text' ...>``
264 265
 
265  
-    Takes one optional argument:
  266
+    Takes same arguments as :class:`TextInput`, with one more optional argument:
266 267
 
267 268
     .. attribute:: DateTimeInput.format
268 269
 
@@ -279,7 +280,7 @@ commonly used groups of widgets:
279 280
 
280 281
     Time input as a simple text box: ``<input type='text' ...>``
281 282
 
282  
-    Takes one optional argument:
  283
+    Takes same arguments as :class:`TextInput`, with one more optional argument:
283 284
 
284 285
     .. attribute:: TimeInput.format
285 286
 
18  tests/regressiontests/forms/tests/widgets.py
@@ -31,9 +31,9 @@ def test_textinput(self):
31 31
         self.assertHTMLEqual(w.render('email', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'}), '<input type="text" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" class="fun" />')
32 32
 
33 33
         # You can also pass 'attrs' to the constructor:
34  
-        w = TextInput(attrs={'class': 'fun'})
35  
-        self.assertHTMLEqual(w.render('email', ''), '<input type="text" class="fun" name="email" />')
36  
-        self.assertHTMLEqual(w.render('email', 'foo@example.com'), '<input type="text" class="fun" value="foo@example.com" name="email" />')
  34
+        w = TextInput(attrs={'class': 'fun', 'type': 'email'})
  35
+        self.assertHTMLEqual(w.render('email', ''), '<input type="email" class="fun" name="email" />')
  36
+        self.assertHTMLEqual(w.render('email', 'foo@example.com'), '<input type="email" class="fun" value="foo@example.com" name="email" />')
37 37
 
38 38
         # 'attrs' passed to render() get precedence over those passed to the constructor:
39 39
         w = TextInput(attrs={'class': 'pretty'})
@@ -915,8 +915,8 @@ def test_datetimeinput(self):
915 915
         self.assertHTMLEqual(w.render('date', datetime.datetime(2007, 9, 17, 12, 51)), '<input type="text" name="date" value="2007-09-17 12:51:00" />')
916 916
 
917 917
         # Use 'format' to change the way a value is displayed.
918  
-        w = DateTimeInput(format='%d/%m/%Y %H:%M')
919  
-        self.assertHTMLEqual(w.render('date', d), '<input type="text" name="date" value="17/09/2007 12:51" />')
  918
+        w = DateTimeInput(format='%d/%m/%Y %H:%M', attrs={'type': 'datetime'})
  919
+        self.assertHTMLEqual(w.render('date', d), '<input type="datetime" name="date" value="17/09/2007 12:51" />')
920 920
         self.assertFalse(w._has_changed(d, '17/09/2007 12:51'))
921 921
 
922 922
         # Make sure a custom format works with _has_changed. The hidden input will use
@@ -938,8 +938,8 @@ def test_dateinput(self):
938 938
         self.assertHTMLEqual(w.render('date', '2007-09-17'), '<input type="text" name="date" value="2007-09-17" />')
939 939
 
940 940
         # Use 'format' to change the way a value is displayed.
941  
-        w = DateInput(format='%d/%m/%Y')
942  
-        self.assertHTMLEqual(w.render('date', d), '<input type="text" name="date" value="17/09/2007" />')
  941
+        w = DateInput(format='%d/%m/%Y', attrs={'type': 'date'})
  942
+        self.assertHTMLEqual(w.render('date', d), '<input type="date" name="date" value="17/09/2007" />')
943 943
         self.assertFalse(w._has_changed(d, '17/09/2007'))
944 944
 
945 945
         # Make sure a custom format works with _has_changed. The hidden input will use
@@ -963,8 +963,8 @@ def test_timeinput(self):
963 963
         self.assertHTMLEqual(w.render('time', '13:12:11'), '<input type="text" name="time" value="13:12:11" />')
964 964
 
965 965
         # Use 'format' to change the way a value is displayed.
966  
-        w = TimeInput(format='%H:%M')
967  
-        self.assertHTMLEqual(w.render('time', t), '<input type="text" name="time" value="12:51" />')
  966
+        w = TimeInput(format='%H:%M', attrs={'type': 'time'})
  967
+        self.assertHTMLEqual(w.render('time', t), '<input type="time" name="time" value="12:51" />')
968 968
         self.assertFalse(w._has_changed(t, '12:51'))
969 969
 
970 970
         # Make sure a custom format works with _has_changed. The hidden input will use

0 notes on commit f1bdfbd

Please sign in to comment.
Something went wrong with that request. Please try again.