Reputation: 1717
I'd like to display django my error messages inside the form as a placeholder, instead of above the form input box itself. Is this possible in Django, or would I have to achieve this by writing some Javascript?
<div class="form-group">
{% if login_form.password.errors %}
{% for error in login_form.password.errors %}
<p>{{ error }}</p>
{% endfor %}
{% endif %}
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span>
{{ login_form.password | placeholder:"password" | addClass:"form-control" }}
</div>
</div>
Specific lines of interest. I'd like to change this:
{{ login_form.password | placeholder:"password" | addClass:"form-control" }}
To this
{{ login_form.password | placeholder:{{ error }} | addClass:"form-control" }}
where {{error}} is an the Django error message thrown by the form
I'm thinking there must be some way of getting the string value of a template variable, but can't find any answers
EDIT: I've tried the following, to no avail
<div class="form-group">
{% if login_form.password.errors %}
{% for error in login_form.password.errors %}
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span>
{{ login_form.password | placeholder:{{ error|escape }} | addClass:"form-control" }}
</div>
{% endfor %}
{% endif %}
</div>
My custom templatetag looks as follows
@register.filter(name='placeholder')
def placeholder(value, token):
value.field.widget.attrs["placeholder"] = token
return value
Django throws a TemplateSyntax Error complaining that:
placeholder requires 2 arguments, 1 provided
Upvotes: 0
Views: 972
Reputation: 811
First, the nested expression in django template system is incorrect, so placeholder
's filter argument shouldn't be enclosed in double brackets, but written directly:
{{ login_form.password | placeholder:error | addClass:"form-control" }}
Here, error
variable is correctly evaluated in context of outer curly brackets scope.
Second, I'd suggest make sure about filter argument's type. If you do expect string value, you may use built-in filter to make an explicit conversion:
{% with err_msg=error|stringformat:"s" %}
{{ login_form.password | placeholder:err_msg | addClass:"form-control" }}
{% endwith %}
Upvotes: 2
Reputation: 890
I have not tested yet, but this may work:
# forms.py
class MyForm(forms.Form):
class meta:
model = MyModel
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
error_messages = self.fields['myfield'].error_messages
self.fields['myfield'].widget.attrs.update({'placeholder': error_messages})
Upvotes: 1
Reputation: 2475
This can be done.
{{ login_form.password.errors }}
Here's the relevant documentation for that https://docs.djangoproject.com/en/1.9/topics/forms/#rendering-form-error-messages
The piece of code should be re-written as
{{ login_form.password | placeholder:"password" | addClass:"form-control" }}
{% if login_form.password.errors %}
<span class="error">{{ login_form.password.errors }}</span>
{% endif %}
or can be done in this way too
{{ login_form.password | placeholder:"password" | addClass:"form-control" }}
<input type="password" class="form-control" placeholder="
{% if login_form.password.errors %}
{{ login_form.password.errors }}
{% else %}
password
{% endif %}
">
Upvotes: 1