Question

I have a form which has an User entity item.

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('user', 'entity', array(/* ... */));
}

I'd like to access the entity's methods in my template. For example, in a User List where admin can select some users, who are not admin, and remove them from database:

{% block body %}
{% for user in form.user %}
    {% if user.isAdmin %}
        {# Disable the checkbox #}
    {% else %}
        {# Render normally #}
    {% endif %}
{% endfor %}
{% endblock %}

However, when I run my application, Symfony tells me that this method isAdmin doesn't exist for object Symfony\Component\Form\FormView.

I haven't been able to find any solution (tried using user.vars.value). Is there a way to do this?

Edit: I'm using Symfony 2.4.2 .

Was it helpful?

Solution

You do not have to pass users to your view. Just create a UsersType with multiple choices enabled and do what you want to do on submit. The following code has not been tested.

class UsersType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('users', 'entity', array(
            'required'      => false,
            'class'         => 'MeMyBundle:UserEntity',
            'property'      => 'id',
            'property_path' => '[id]', # in square brackets!
            'multiple'      => true,
            'expanded'      => true
        ));
    }
}

Create your controller action

/**
 * @Route("/my_users", name="_users")
 * @Template()
 */
public function usersAction()
{
    $request = $this->get('request');
    $users = $this->get('my_user_manager')->findAll() //get all users. Fit this line depending on your app.
    $form = $this->createForm(new UsersType(), $users); // I assume you have a UsersType here.

    $form->bind($request);
    if ($form->isValid()) {
        $data = $form->getData();
        foreach ($data['users'] as $user) {
            // Do what you want with $user, it contains one selected user
        }
        //you can redirect here
    }

    return array(
        'users' => $users,
        'form' => $form->createView(),
    );
}

Now in your view, you can select your users :

{% block body %}
{% if is_granted('ROLE_ADMIN') %}
    {{ form_start(form) }}
        {{ form_errors(form) }}
        ...
        <input type="submit" />
    {{ form_end(form) }}
{% else %}
        {# Render a list #}
        <ul>
        {% for user in users %}
            <li>{{user.username}}</li>
        {% endfor %}
        </ul>
{% endif %}
{% endblock %}

OTHER TIPS

I think the best way to go for this is a Custom Form Type. So in your current form use this:

$builder->add('user', 'user', array(/* ... */));

And create your own UserType:

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class UserType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // ... implement your logic...
    }

    public function buildView(FormView $view, FormInterface $form, array $options)
    {
       // here you can set the isAdmin value
       // $view->vars['is_admin']
       // you can access your data via $form->getData()
    }

    public function getParent()
    {
        return 'choice';
    }

    public function getName()
    {
        return 'user';
    }
}

Now you can create your own template based on that:

{# src/Acme/DemoBundle/Resources/views/Form/fields.html.twig #}
{% block user_widget %}
    {# This will check a value when the user is admin: #}
    {% set is_selected is_admin %}
    {# let the original widget do the rest: #}
    {{ block('choice_widget') }}
{% endblock %}

Also make sure to add this to your config.yml

twig:
    form:
        resources:
            - 'AcmeDemoBundle:Form:fields.html.twig'

Another answer (not tested):

/**
 * @Route("/my_users", name="_users")
 * @Template()
 */
public function usersAction()
{
    $request = $this->get('request');
    $users = $this->get('my_user_manager')->findAll() //get all users. Fit this line depending on your app.

    if ("POST" === $request->getMethod()) {
        $data = $request->request->get('users');
        //Do what you want with submitted data
    }

    return array(
        'users' => $users,
    );
}

Your view:

{% block body %}
<form action="{{ path("_users") }}" method="post">
    <table>
       <caption>Users</caption>
       <thead>
          <tr>
             {% if is_granted('ROLE_ADMIN') %}
             <th>Is admin?</th>
             {% endif %}
             <th>Username</th>
          </tr>
       </thead>
       <tbody>
          <tr>
             {% if is_granted('ROLE_ADMIN') %}
             <td>
                 <input class="{% if user.isAdmin() %}admin{% else %}notadmin{% endif %}" type="checkbox" id="user_{{user.getId()}}" name="users[]" value="{{user.getId()}}"{% if user.isAdmin() %} checked{% endif %} />
             </td>
             {% endif %}
             <td>{{user.getUsername()}}</td>
          </tr>
       </tbody>
    </table>
    <input type="submit" />
</form>
{% endblock %}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top