Question

I have a dropdown menu in my form and the form structure depends on its value. I have managed to solve the "form-update-issue" with event subscriber/listener class, where i am trying to update the main form according to dropdown's value.

The main problem is that i have to modify the form from values that persisted in the database. My DB schema:

I have 4 table: Model, ModelCategory, ModelCategoryKey, ModelParameter.

  • ModelCategory 1--n Model 1--m ModelParameter
  • ModelCategory 1--n ModelCategoryKey
  • ModelCategoryKey 1--n ModelParameter

After the user choose a ModelCategory from the form's (form based on Model entity) dropdown i have to update the form with ModelParamater rows, but it's number and default values depends on ModelCategory 1--n ModelCategoryKey assocaiton.

I've tried to attach NEW ModelParameter entities to the main Model entity during the PRE_BIND event (also set their default values) and it seems working fine, but when i add the 'parameters' with a 'collection' typed element to the form i get the next error:

Entities passed to the choice field must be managed. Maybe persist them in the entity manager?

Clearly my entities can't be (and shouldn't be) persisted at this time.

All ideas are welcome!

UPDATE: Modifying the form after preSubmit/preBind:

$form->add('parameters','collection',array(
    'type' => new ModelParameterType(),         
));

OR

$form->add(
            $this->factory->createNamed('parameters','collection',null,
                array(
                    'type' => new ModelParameterType()
                    ))
        );

where the 'factory' attribute is a FormFactoryInterface. The error message is the same.

UPDATE2:

Further investigation proved, that if i don't add "default" entities to the assocation. Then it works without error.

Here is the source of my form modifying method:

public function preSubmit(FormEvent $event) {
    $form = $event->getForm();  
    $id = $event->getData()['modelCategory'];       
    $entity = $form->getData();
    $categoryKeys = $this->em->getRepository('MyBundle:ModelCategoryKey')->findByModelCategory(
        $this->em->getReference('MyBundle:modelCategory',$id)
    );      
    foreach ($categoryKeys as $key) {
        $param = new ModelParameter();
        $param->setModel($entity);
        $param->setKey($key); 
        $entity->addParameter($param);
    }

    $form->add(
        $this->factory->createNamed('parameters','collection',null,
            array(
                'type' => new ModelParameterType(),
                'allow_add' => true,
                'cascade_validation' => true
                ))
    );

}

SEEMS TO BE SOLVED BY I have just commented out the $param->setModel($entity); line and it seems to be working fine. I will work this out more and will share the experience, if it realy works.

Was it helpful?

Solution 2

I've managed to solve my problem, so here it is what i've found out:

  • It is enough to add the newly created object by the adder function of the inverse side. I don't have to call the owning side's setter.
  • Inverse side adder function must be modified, that it calls the owning side's setter.
  • Inverse side adder function must check if the object is not in the collection already.
  • PRE_SET_DATA event happens, when the form is created. (so in new entities it is empty, and in old ones it is filled)

OTHER TIPS

choice field accepts only managed entities, as the value is set to the entity after submit, and form posts only entities ID, so it must be saved beforehand.

You don't need choice field - you need collection of parameter subforms.

$formBuilder
    ->add('category', 'category_select')
    ->add('parameters', 'collection', array('type' => 'parameter'))
;

I'm assuming here that category_select is choice field with categories and parameter is subform with it's own values, depending on your parameter structure.

When you have category in your controller, you can bind the newly created entity with added Parameter entities with their key set, depending on ModelCategoryKey.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top