1

I have a user creation form (on top of Symfony Form component), it's used on some different pages and is loaded via AJAX.

An initial request contains information we already know about a user-to-be, e.g. if form is loaded from a manager creation page for the "X" company, we already know that a user has a role = "manager" and company = "X". And the corresponding form fields must be removed/hidden from the form and underlying user object must be provided with these parameters (a role field must be set to "manager", a company field must be set to "X").

How can it be achieved?

Vasily
  • 1,858
  • 1
  • 21
  • 34

1 Answers1

2

From what I understand you can use the answer for this question : https://stackoverflow.com/a/18792299/4098335

Basically, after calling createForm(), you have to call setData() for the desired field.

If this doesn't work, maybe try overriding the constructor for your AbstractType class. But it's a bit "hacky" and clearly not the easiest way... Example here :

class YourUserType extends AbstractType
{
    protected $manager;

    public function __construct($manager = null)
    {
        $this->manager = $manager;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if ($this->manager !== null) {
            $builder
                ->add('manager', 'entity', array(
                        'class' => 'YourBundle:Manager',
                        'data' => $this->manager,
                        'read_only' => true,
                    )
                );
        }
    }
}

Then, in your controller, pass the "manager" entity when you instantiate YourUserType :

    $form = $this->createForm(new YourUserType($manager), $entity, array(
        'action' => $this->generateUrl('create_url'),
        'method' => 'POST',
    ));

Note: in the example I put the 'read_only' option to true, that way you'll 'avoid' the user to select another value. You can hide the field anyway later in front end, but still you should check the value later when dealing with the form request.

Community
  • 1
  • 1
Simon Duflos
  • 133
  • 2
  • 12
  • Thank you, these are quite helpful examples, I eventually did it roughly the same way, but with using $options instead of passing $manager in constructor. But now all that my readonly stuffs are reseted if we have validation errors on form :) And all my readonly select somehow not so readonly - they looks like disabled, but allow to change them, why so? – Vasily Aug 14 '15 at 15:14
  • It turns out select haven't readonly attribute, what makes it unhelpful, because all of that field are rendered in selects – Vasily Aug 14 '15 at 15:17
  • Can you try with the option "disabled" set to true, instead of "read_only" ? – Simon Duflos Aug 14 '15 at 15:19
  • Regarding your other comment about the fact that your fields are not properly set when you have a validation error, make sure that you instantiate your Type class as you do when you create the "original" form. You have to get the manager entity in the controller action where you deal with the form request, and pass it to the YourUserType constructor the same way. – Simon Duflos Aug 14 '15 at 15:23
  • I've already tried it, but values of such fields aren't send to a server. In such a case I should save them on the server, what of course not so bad, but it complicate a logic a bit, but I think I eventually will end up with this variant =) – Vasily Aug 14 '15 at 15:24
  • Yes, you are right, the fields aren't set on a form submission (when validation errors occur) because these predefined fields don't present in a request (and the $options array isn't populated with readonly fields - I use options array instead of $manager you've suggested). They are sent only on initial request and must be stored somewhere during all that subsequent requests in order to properly populate $options array. It seems I should to use session. – Vasily Aug 14 '15 at 15:32