Initialize custom type form data

1.4k views Asked by At

I have defined a custom form like this:

class EditOwnerProfileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add("user", new UserType())
            ->add("dog", new DogType())
            ->add('save', 'submit');
    }

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

I want to create this form and initialize it with some data like this:

    $user = new User();
    $user->setLatitude(1.1)
        ->setLongitude(2.2)
        ->setAddress("custom address");

    $dog = new Dog();
    $dog->setDogName("Bruno")
        ->setDogSize("small")
        ->setDogBreed("Bulldog");

    $formData = array(
        "user" => $user,
        "dog" => $dog
    );

    $form = $this->createForm(new EditOwnerProfileType(), $formData, array("csrf_protection" => false))->handleRequest($request);

DogTypeand UserTypeonly have NotBlank constraints

Every time i want to validate data, it allways throws error for every field like this:

"errors": {
  "user": {
    "latitude": [
      "This value should not be blank."
    ],
    "longitude": [
      "This value should not be blank."
    ],
    "address": [
      "This value should not be blank."
    ]
  },
  "dog": {
    "dogName": [
      "This value should not be blank."
    ],
    "dogSize": [
      "This value should not be blank."
    ],
    "dogBreed": [
      "This value should not be blank."
    ]
  },

Isn't supposed that i'm initializing all the values? So, if user don't pass any value for this field, is initialized with the values I defined? Which is the correct way to initialize values on EditOwnerProfileType form?

EDIT: I tried to change the form creation (just for testing), but didn't work either.

$form = $this->createForm(new EditOwnerProfileType(), $formData, array("csrf_protection" => false));
$form->setData($formData);
$form->handleRequest($request);

EDIT2: To include DogType and UserType code

class DogType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('dogSize')
            ->add('dogBreed')            
        ;
    }    

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Dog',
        ));
    }

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

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('latitude')
            ->add('longitude')
            ->add('address')
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\User',
        ));
    }

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

I'm using Symfony 2.7.9

1

There are 1 answers

0
Pipe On

I answer my own question, the problem was... I was misunderstanding the Symfony Form Component.

I can initialize the form like:

$user = new User();
$user->setLatitude(1.1)
    ->setLongitude(2.2)
    ->setAddress("custom address");

$dog = new Dog();
$dog->setDogName("Bruno")
    ->setDogSize("small")
    ->setDogBreed("Bulldog");

$formData = array(
    "user" => $user,
    "dog" => $dog
);

$form = $this->createForm(new EditOwnerProfileType(), $formData, array("csrf_protection" => false))

At this point, the form is correctly initialized and all fields have the correct values.

Passing one parameter in the request edit_owner[dog][name]=othername and doing:

$form->handleRequest($request);

I expected only the edit_owner[dog][name] to be changed (And the rest of fields maintain its default value), but i noticed that the rest of fields of the form were processed and parsed as blank values and replaced my "initial values".

That was the problem and Symfony works on that way. I make this answer so it can be useful for someone else.