How do I add a placeholder on a CharField in Django?
Take this very simple form for example:
class SearchForm(Form):
q = forms.CharField(label='search')
This gets rendered in the template:
<input type="text" name="q" id="id_q" />
However, I want to add the placeholder
attribute to this field with a value of Search
so that the HTML would look something like:
<input type="text" name="q" id="id_q" placeholder="Search" />
Preferably I would like to pass the placeholder value in to CharField
in the form class through a dictionary or something like:
q = forms.CharField(label='search', placeholder='Search')
What would be the best way to accomplish this?
Solution 1:
Look at the widgets documentation. Basically it would look like:
q = forms.CharField(label='search',
widget=forms.TextInput(attrs={'placeholder': 'Search'}))
More writing, yes, but the separation allows for better abstraction of more complicated cases.
You can also declare a widgets
attribute containing a <field name> => <widget instance>
mapping directly on the Meta
of your ModelForm
sub-class.
Solution 2:
For a ModelForm, you can use the Meta class thus:
from django import forms
from .models import MyModel
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'name': forms.TextInput(attrs={'placeholder': 'Name'}),
'description': forms.Textarea(
attrs={'placeholder': 'Enter description here'}),
}
Solution 3:
The other methods are all good. However, if you prefer to not specify the field (e.g. for some dynamic method), you can use this:
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['email'].widget.attrs['placeholder'] = self.fields['email'].label or '[email protected]'
It also allows the placeholder to depend on the instance for ModelForms with instance specified.
Solution 4:
Great question. There are three solutions I know about:
Solution #1
Replace the default widget.
class SearchForm(forms.Form):
q = forms.CharField(
label='Search',
widget=forms.TextInput(attrs={'placeholder': 'Search'})
)
Solution #2
Customize the default widget. If you're using the same widget that the field usually uses then you can simply customize that one instead of instantiating an entirely new one.
class SearchForm(forms.Form):
q = forms.CharField(label='Search')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['q'].widget.attrs.update({'placeholder': 'Search'})
Solution #3
Finally, if you're working with a model form then (in addition to the previous two solutions) you have the option to specify a custom widget for a field by setting the widgets
attribute of the inner Meta
class.
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
widgets = {
'body': forms.Textarea(attrs={'cols': 80, 'rows': 20})
}