Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 form_errors

Tags:

php

symfony

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

like image 619
TroodoN-Mike Avatar asked Dec 28 '11 11:12

TroodoN-Mike


2 Answers

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.

like image 110
Kris Wallsmith Avatar answered Sep 27 '22 18:09

Kris Wallsmith


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.

like image 25
TroodoN-Mike Avatar answered Sep 27 '22 18:09

TroodoN-Mike