5

I think its a simple question. Its about outputting errors. This is my twig file:

    <table>
        <tr>
            <td>{{ form_label(form.dueDate) }}</td>
            <td>{{ form_widget(form.dueDate) }}</td>
            <td>{{ form_errors(form.dueDate) }}</td>
        </tr>
        <tr>
            <td>{{ form_label(form.task) }}</td>
            <td>{{ form_widget(form.task) }}</td>
            <td>{{ form_errors(form.task) }}</td>
        </tr>
    </table>

Now each error displays (td with form_errors()) as:

< ul>< li>This value should not be blank< /li>< /ul>

My question is: I want to output error as plain text (without ul and li).

I know there is an example like this:

{% for error in errors %}
    {{ error.message }}        
{% endfor %}

But this will output errors one after another. I want to display them where specific input is:

< td>{{ myErrorFor form.dueDate }}< /td>

Big thanks for any help

TroodoN-Mike
  • 15,687
  • 15
  • 55
  • 78
  • I'm not sure there is a way to do this. It may be necessary to write a new Twig extension (not that hard, IIRC). The quick and easy way, of course, would be to remove the styling from the `ul` and `li`... – lonesomeday Dec 28 '11 at 11:42
  • I like your idea, but im sure there is an easier way... – TroodoN-Mike Dec 28 '11 at 12:22

4 Answers4

13

You can customize how form errors render by providing your own form theme with a field_errors block.

You can do this for just the current template:

{# tell the form to look for theme blocks in the current template #}
{% form_theme form _self %}

{% block field_errors %}
{% for error in errors %}
{{ error.messageTemplate|trans(error.messageParameters, 'validators') }}<br>
{% endfor %}
{% endblock %}

{# the rest of your template... #}

Or by defining a global form theme in config.yml:

twig:
    form: { resource: "::form_theme.html.twig" }

In this case you would want to move the field_errors block above to app/Resources/views/form_theme.html.twig and the form_theme tag is no longer necessary.

Kris Wallsmith
  • 8,945
  • 1
  • 37
  • 25
  • If I go with the global form theme, what do I have to do in the form template (not `form_theme.html.twig` but my actual form itself) to get it to work? – Jason Swett Apr 03 '12 at 19:11
2

Here is my solution. I have decided to create an array with errors and pass it into the view (twig). It took me a while to work out how to get error messages... but here we go:

    // Controller example: 
    public function indexAction(Request $request)
    {
    $task = new \Michael\MikeBundle\Entity\Task();
    $task->setTask('Write a blog post');
    $task->setDueDate(new \DateTime('tomorrow'));
    
    $form = $this->createFormBuilder($task)
         ->add('task', 'text', 
                 array('attr' => array('title' => 'Enter Task')))
         ->add('dueDate', 'date', array(
             'widget' => 'single_text',
             'required' => false,
             'attr' => array('title' => 'Insert due date')))
         ->getForm();

    // If user submitted code
    if ($request->getMethod() == 'POST') {
            // Get form part from request
            $request->request->get('form');    
            
            // Bind request into the form
            $form->bindRequest($request);
        }
        
    // Pass into the view
    return array('errors' => $this->_getErrors($form), 'form' => $form->createView());
    }

    protected function _getErrors($form)
    {
    // Validate form
    $errors = $this->get('validator')->validate($form);
    
    // Prepare collection
    $collection = array();
    
    // Loop through each element of the form
    foreach ($form->getChildren() as $key => $child) {
        $collection[$key] = "";
    }
    
    foreach ($errors as $error) {
        $collection[str_replace("data.", "", $error->getPropertyPath())] = $error->getMessage();
    }
    return $collection;
    }

The important part is method _getErrors($form) as it returns an array like this (if there are errors)

$errors['task'] = This value should not be blank

$errors['dueDate'] = ""

And here is twig part:

    <table>
        <tr>
            <td>{{ form_label(form.dueDate) }}</td>
            <td>{{ form_widget(form.dueDate) }}</td>
            <td>{{ errors[form.dueDate.vars["name"]] }}</td>
        </tr>
        <tr>
            <td>{{ form_label(form.task) }}</td>
            <td>{{ form_widget(form.task) }}</td>
            <td>{{ errors[form.task.vars["name"]] }}</td>
        </tr>
    </table>

I hope its clear enough. Let me know if you need help.

Please post answer if there is an easier way to do it.

Community
  • 1
  • 1
TroodoN-Mike
  • 15,687
  • 15
  • 55
  • 78
  • http://stackoverflow.com/questions/6978723/symfony2-how-to-get-form-validation-errors-after-binding-the-request-to-the-fo/8216192#8216192 May be a simpler way to accomplish getting the errors array. – Icode4food Jul 03 '12 at 13:47
1

Can't add comments yet, but I would like to update Kris Wallsmith's answer. Nowadays this block is called form_errors, so in 3rd line it should be {% block field_errors %}. It took me a while to investigate, hopefully someone benefits from that.

pstryk
  • 1,991
  • 1
  • 14
  • 11
1

Another simple solution (tested with symfony 3):

{% for error in form.username.vars.errors %}
   {{ error.message }} <br/>
{% endfor %}

Replace 'username' with your form field.

Mohamed Ramrami
  • 12,026
  • 4
  • 33
  • 49