Ticket #16630: html5-input-types-take3.patch
File html5-input-types-take3.patch, 8.0 KB (added by , 13 years ago) |
---|
-
django/forms/fields.py
diff --git a/django/forms/fields.py b/django/forms/fields.py index 49f29db..581101a 100644
a b except ImportError: 18 18 from django.core import validators 19 19 from django.core.exceptions import ValidationError 20 20 from django.forms.util import ErrorList, from_current_timezone, to_current_timezone 21 from django.forms.widgets import (TextInput, PasswordInput, HiddenInput, 21 from django.forms.widgets import ( 22 TextInput, IntegerInput, PasswordInput, EmailInput, URLInput, HiddenInput, 22 23 MultipleHiddenInput, ClearableFileInput, CheckboxInput, Select, 23 24 NullBooleanSelect, SelectMultiple, DateInput, DateTimeInput, TimeInput, 24 SplitDateTimeWidget, SplitHiddenDateTimeWidget, FILE_INPUT_CONTRADICTION) 25 SplitDateTimeWidget, SplitHiddenDateTimeWidget, FILE_INPUT_CONTRADICTION 26 ) 25 27 from django.utils import formats 26 28 from django.utils.encoding import smart_unicode, smart_str, force_unicode 27 29 from django.utils.ipv6 import clean_ipv6_address … … from django.utils.translation import ugettext_lazy as _ 30 32 # Provide this import for backwards compatibility. 31 33 from django.core.validators import EMPTY_VALUES 32 34 33 34 35 __all__ = ( 35 36 'Field', 'CharField', 'IntegerField', 36 37 'DateField', 'TimeField', 'DateTimeField', 'TimeField', … … class CharField(Field): 198 199 199 200 def widget_attrs(self, widget): 200 201 attrs = super(CharField, self).widget_attrs(widget) 201 if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)):202 if self.max_length is not None and isinstance(widget, TextInput): 202 203 # The HTML attribute is maxlength, not max_length. 203 204 attrs.update({'maxlength': str(self.max_length)}) 204 205 return attrs 205 206 206 207 class IntegerField(Field): 208 widget = IntegerInput 207 209 default_error_messages = { 208 210 'invalid': _(u'Enter a whole number.'), 209 211 'max_value': _(u'Ensure this value is less than or equal to %(limit_value)s.'), … … class IntegerField(Field): 235 237 raise ValidationError(self.error_messages['invalid']) 236 238 return value 237 239 240 def widget_attrs(self, widget): 241 attrs = super(IntegerField, self).widget_attrs(widget) 242 if self.min_value: 243 attrs['min'] = self.min_value 244 if self.max_value: 245 attrs['max'] = self.max_value 246 return attrs 247 238 248 class FloatField(IntegerField): 239 249 default_error_messages = { 240 250 'invalid': _(u'Enter a number.'), … … class FloatField(IntegerField): 256 266 raise ValidationError(self.error_messages['invalid']) 257 267 return value 258 268 259 class DecimalField(Field): 269 def widget_attrs(self, widget): 270 attrs = super(FloatField, self).widget_attrs(widget) 271 attrs['step'] = 'any' 272 return attrs 273 274 class DecimalField(IntegerField): 260 275 default_error_messages = { 261 276 'invalid': _(u'Enter a number.'), 262 'max_value': _(u'Ensure this value is less than or equal to %(limit_value)s.'),263 'min_value': _(u'Ensure this value is greater than or equal to %(limit_value)s.'),264 277 'max_digits': _('Ensure that there are no more than %s digits in total.'), 265 278 'max_decimal_places': _('Ensure that there are no more than %s decimal places.'), 266 279 'max_whole_digits': _('Ensure that there are no more than %s digits before the decimal point.') 267 280 } 268 281 269 282 def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): 270 self.max_value, self.min_value = max_value, min_value271 283 self.max_digits, self.decimal_places = max_digits, decimal_places 272 Field.__init__(self, *args, **kwargs) 273 274 if max_value is not None: 275 self.validators.append(validators.MaxValueValidator(max_value)) 276 if min_value is not None: 277 self.validators.append(validators.MinValueValidator(min_value)) 284 super(DecimalField, self).__init__(max_value, min_value, *args, **kwargs) 278 285 279 286 def to_python(self, value): 280 287 """ … … class DecimalField(Field): 323 330 raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) 324 331 return value 325 332 333 def widget_attrs(self, widget): 334 attrs = super(DecimalField, self).widget_attrs(widget) 335 if self.max_digits: 336 attrs['maxlength'] = self.max_digits + 1 # for the dot 337 if self.decimal_places: 338 attrs['step'] = '0.%s1' % ('0' * (self.decimal_places-1)) 339 return attrs 340 326 341 class BaseTemporalField(Field): 327 342 328 343 def __init__(self, input_formats=None, *args, **kwargs): … … class RegexField(CharField): 459 474 regex = property(_get_regex, _set_regex) 460 475 461 476 class EmailField(CharField): 477 widget = EmailInput 462 478 default_error_messages = { 463 479 'invalid': _(u'Enter a valid e-mail address.'), 464 480 } … … class ImageField(FileField): 585 601 return f 586 602 587 603 class URLField(CharField): 604 widget = URLInput 588 605 default_error_messages = { 589 606 'invalid': _(u'Enter a valid URL.'), 590 607 } -
django/forms/widgets.py
diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 1fbef98..5ca7186 100644
a b from django.utils.safestring import mark_safe 19 19 from django.utils import datetime_safe, formats 20 20 21 21 __all__ = ( 22 'Media', 'MediaDefiningClass', 'Widget', 'TextInput', 'PasswordInput', 23 'HiddenInput', 'MultipleHiddenInput', 'ClearableFileInput', 24 'FileInput', 'DateInput', 'DateTimeInput', 'TimeInput', 'Textarea', 'CheckboxInput', 25 'Select', 'NullBooleanSelect', 'SelectMultiple', 'RadioSelect', 26 'CheckboxSelectMultiple', 'MultiWidget', 27 'SplitDateTimeWidget', 22 'Media', 'MediaDefiningClass', 'Widget', 'TextInput', 'EmailInput', 'URLInput', 23 'IntegerInput', 'PasswordInput', 'HiddenInput', 'MultipleHiddenInput', 24 'ClearableFileInput', 'FileInput', 'DateInput', 'DateTimeInput', 'TimeInput', 25 'Textarea', 'CheckboxInput', 'Select', 'NullBooleanSelect', 'SelectMultiple', 26 'RadioSelect', 'CheckboxSelectMultiple', 'MultiWidget', 'SplitDateTimeWidget', 28 27 ) 29 28 30 29 MEDIA_TYPES = ('css','js') … … class Input(Widget): 242 241 """ 243 242 input_type = None # Subclasses must define this. 244 243 244 def __init__(self, attrs=None, input_type=None): 245 if input_type is not None: 246 self.input_type = input_type 247 super(Input, self).__init__(attrs) 248 245 249 def _format_value(self, value): 246 250 if self.is_localized: 247 251 return formats.localize_input(value) … … class Input(Widget): 259 263 class TextInput(Input): 260 264 input_type = 'text' 261 265 262 class PasswordInput(Input): 266 class IntegerInput(TextInput): 267 input_type = 'number' 268 269 class EmailInput(TextInput): 270 input_type = 'email' 271 272 class URLInput(TextInput): 273 input_type = 'url' 274 275 class PasswordInput(TextInput): 263 276 input_type = 'password' 264 277 265 278 def __init__(self, attrs=None, render_value=False): … … class Textarea(Widget): 395 408 return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs), 396 409 conditional_escape(force_unicode(value)))) 397 410 398 class DateInput(Input): 399 input_type = 'text' 400 411 class DateInput(TextInput): 401 412 def __init__(self, attrs=None, format=None): 402 413 super(DateInput, self).__init__(attrs) 403 414 if format: … … class DateInput(Input): 426 437 pass 427 438 return super(DateInput, self)._has_changed(self._format_value(initial), data) 428 439 429 class DateTimeInput(Input): 430 input_type = 'text' 431 440 class DateTimeInput(TextInput): 432 441 def __init__(self, attrs=None, format=None): 433 442 super(DateTimeInput, self).__init__(attrs) 434 443 if format: … … class DateTimeInput(Input): 457 466 pass 458 467 return super(DateTimeInput, self)._has_changed(self._format_value(initial), data) 459 468 460 class TimeInput(Input): 461 input_type = 'text' 462 469 class TimeInput(TextInput): 463 470 def __init__(self, attrs=None, format=None): 464 471 super(TimeInput, self).__init__(attrs) 465 472 if format: