mirror of
https://github.com/django/django.git
synced 2024-12-23 01:25:58 +00:00
Fixed #32340 -- Improved usability for form fields with specific input patterns.
This commit is contained in:
parent
f05edb2b43
commit
693cedc532
@ -29,6 +29,7 @@ from django.forms.widgets import (
|
||||
EmailInput,
|
||||
FileInput,
|
||||
HiddenInput,
|
||||
Input,
|
||||
MultipleHiddenInput,
|
||||
NullBooleanSelect,
|
||||
NumberInput,
|
||||
@ -1408,3 +1409,17 @@ class JSONField(CharField):
|
||||
return json.dumps(initial, sort_keys=True, cls=self.encoder) != json.dumps(
|
||||
self.to_python(data), sort_keys=True, cls=self.encoder
|
||||
)
|
||||
|
||||
|
||||
class CustomField:
|
||||
def __init__(self, *, widget=None, placeholder=None, **kwargs):
|
||||
self.placeholder = placeholder
|
||||
if widget:
|
||||
self.widget = widget
|
||||
else:
|
||||
self.widget = Input()
|
||||
|
||||
if self.placeholder:
|
||||
self.widget.attrs.setdefault("placeholder", self.placeholder)
|
||||
|
||||
super().__init__(**kwargs)
|
||||
|
@ -1 +1,3 @@
|
||||
<input type="{{ widget.type }}" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value|stringformat:'s' }}"{% endif %}{% include "django/forms/widgets/attrs.html" %}>
|
||||
|
||||
{% if widget.attrs.placeholder %}placeholder="{{ widget.attrs.placeholder }}" {% endif %}>
|
||||
|
@ -1226,3 +1226,25 @@ class SelectDateWidget(Widget):
|
||||
("{}_{}".format(name, interval) in data)
|
||||
for interval in ("year", "month", "day")
|
||||
)
|
||||
|
||||
|
||||
class Input(Widget):
|
||||
input_type = None # Subclass must define this
|
||||
|
||||
def __init__(self, attrs=None, placeholder=None):
|
||||
self.placeholder = placeholder # Add placeholder attribute
|
||||
super().__init__(attrs)
|
||||
|
||||
def get_context(self, name, value, attrs):
|
||||
context = super().get_context(name, value, attrs)
|
||||
if self.placeholder:
|
||||
attrs = attrs or {}
|
||||
attrs.setdefault("placeholder", self.placeholder)
|
||||
context["widget"]["attrs"] = attrs
|
||||
return context
|
||||
|
||||
def render(self, name, value, attrs=None, renderer=None):
|
||||
attrs = attrs or {}
|
||||
if self.placeholder:
|
||||
attrs["placeholder"] = self.placeholder
|
||||
return super().render(name, value, attrs, renderer)
|
||||
|
@ -1627,3 +1627,13 @@ only requirements are that it implement a ``clean()`` method and that its
|
||||
|
||||
You can also customize how a field will be accessed by overriding
|
||||
:meth:`~django.forms.Field.get_bound_field()`.
|
||||
|
||||
DateField
|
||||
---------
|
||||
Use this field to input dates. The default expected format is ``YYYY-MM-DD``.
|
||||
For example: ``2024-12-31``.
|
||||
|
||||
TimeField
|
||||
---------
|
||||
Use this field to input time. The default expected format is ``HH:MM``.
|
||||
For example: ``14:30``.
|
@ -1,5 +1,6 @@
|
||||
from django.contrib.admin.tests import AdminSeleniumTestCase
|
||||
from django.test import override_settings
|
||||
from django.forms import CharField, Form, TextInput
|
||||
from django.test import SimpleTestCase, override_settings
|
||||
from django.urls import reverse
|
||||
|
||||
from ..models import Article
|
||||
@ -22,3 +23,17 @@ class LiveWidgetTests(AdminSeleniumTestCase):
|
||||
self.selenium.find_element(By.ID, "submit").click()
|
||||
article = Article.objects.get(pk=article.pk)
|
||||
self.assertEqual(article.content, "\r\nTst\r\n")
|
||||
|
||||
|
||||
class WidgetPlaceholderTests(SimpleTestCase):
|
||||
def test_placeholder_in_input_widget(self):
|
||||
widget = TextInput(attrs={"placeholder": "Enter text"})
|
||||
output = widget.render("name", "")
|
||||
self.assertIn('placeholder="Enter text"', output)
|
||||
|
||||
def test_placeholder_in_field(self):
|
||||
class ExampleForm(Form):
|
||||
name = CharField(widget=TextInput(attrs={"placeholder": "Your name"}))
|
||||
|
||||
form = ExampleForm()
|
||||
self.assertIn('placeholder="Your name"', str(form["name"]))
|
||||
|
Loading…
Reference in New Issue
Block a user