Error Formatting for Twitter Bootstrap
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
Error Formatting for Twitter Bootstrap¶
Submit the form with some bad data. Oh, it’s terrible. The errors, they’re so ugly. We must fix this.
Go back to form_div_layout.html.twig. We don’t know which block renders errors, but if you search for the word “errors”, you’ll find it: form_errors.
Copy it into our template:
{# app/Resources/views/form_theme.html.twig #}
{# ... #}
{% block form_errors %}
{% if errors|length > 0 %}
<ul>
{% for error in errors %}
<li>{{ error.message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock form_errors %}
Here’s the plan. Give the ul a help-block class. This class is from Twitter Bootstrap:
{# app/Resources/views/form_theme.html.twig #}
{# ... #}
{% block form_errors %}
{% if errors|length > 0 %}
<ul class="help-block">
{% for error in errors %}
<li>{{ error.message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock form_errors %}
Refresh. It’s a very minor improvement, but we’ve at least modified our second form block. I’ll leave the bullet point, but if you want to add some CSS to get rid of it, be my guest. It is ugly.
Next, let’s see if we can highlight the error message in red. Hardcode a has-error field to the div in form_row:
{# app/Resources/views/form_theme.html.twig #}
{% block form_row %}
<div class="form-group has-error">
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endblock form_row %}
Refresh. This worked, we have red error text but in a second this class is also going to turn the fields red. But we don’t want every field to always look like an emergency, so what can we do?
Form Variables: The Holy Grail of Form Rendering Control¶
Inside the form_errors block, we have access to some errors variable. In fact, in each block we have access to a bunch of variables, like label, value, name, full_name and required.
Let’s use a trick to see all of the variables we have access to in form_errors:
{# app/Resources/views/form_theme.html.twig #}
{# ... #}
{% block form_errors %}
{{ dump(_context|keys) }}
{% if errors|length > 0 %}
<ul class="help-block">
{% for error in errors %}
<li>{{ error.message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock form_errors %}
Tip
dump is a Twig debugging function, like var_dump. You can pass it any variable to print it out.
Refresh! For each field, you now see a giant list - for me, 27 things. All of these are variables that you magically have access to inside a form theme block. And the variables are the same no matter what block you’re in.
Remove the dump call. So we can finally use the errors variable in form_row to only print the class if the field has errors:
{# app/Resources/views/form_theme.html.twig #}
{# ... #}
{% block form_row %}
<div class="form-group {{ errors|length > 0 ? 'has-error' : '' }}">
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endblock form_row %}
{# ... #}
Re-submit, fill in some fields correctly. Cool, we still see the red errors, but the other fields are missing this class. That’s awesome.
8 Comments
Hi there,
My form validation is working partially let alone bootstrap validation. Thanks in advance.
Hey Junaid Farooq!
So... do you mean that form validation IS working, but you don't see the bootstrap styles? Or something different? If so, if you view the HTML source, do you see classes like
form-groupandform-controlin your HTML, or not?Cheers!
Hey weaverryan
Thanks for replying. I meant my server side form validation is not working. No errors are shown. For example if i disable the front end validation and then try to submit an empty form, it doesn't validate the form from the server side instead it tries to insert the data into the database which then throws a db exception. I hope you get what i mean. Cheers!
Hey Junaid,
What validation constraints do you use? And where do you declare it? Because, by default, Symfony does not add some validation on the server side for empty fields, you need to add it by your own.
Cheers!
Hey victor
Thanks for replying. I am using the constraints in the User entity. Following is an example of sych for Username and email:
class User implements AdvancedUserInterface, \Serializable
..................
/**
* @var string
*
* @ORM\Column(name="username", type="string", length=255, unique=true)
* @Assert\NotBlank(message="Username cannot be empty")
* @Assert\Length(min=3, minMessage="Username should be at least 3 characters!")
*/
private $username;
/**
* @var string
*
* @ORM\Column(name="email", type="string", length=255, unique=true)
* @Assert\NotBlank(message="Email cannot be empty")
* @Assert\Email
*
*/
private $email;
...................
Cheers!
Hey Junaid,
Hm, looks legitimate for me if you use the next namespace in User entity:
use Symfony\Component\Validator\Constraints as Assert;
So it really should work. Do you use "$form->isSubmitted() && $form->isValid()" in your controller? Well, try to clear the cache first and if you still have this problem, can you show your form type you use and a part of your controller which relates to this form?
Cheers!
Hey victor
Again Thank you for your prompt response. Back to your response. yes I am using the namespaces required in the User Entity. here are all of them:
To your question: Yes i am using "$form->isSubmitted().....".Here is the whole registerAction():
Here is my RegisterFormType code:
Please have a look and thank you once again for reaching out. Cheers!
Hey Junaid,
Hm, I see a few problems in your code which could cause this validation problems, so let me tweak your code to the best practice and if you're wondering about any changes I made - just ask another question ;) For simplicity, if I only change things of add new ones, so if I'm not sowing something in my code - this means it's the same as in yours.
So, first of all your need to bind RegisterFormType to the entity:
"Houston: no signs of life"
Start the conversation!