I\'ve got a form built in Symfony and when rendered in the view, the html form may or may not contain all of the fields in the form object (the entity sort of has a couple o
In short, don't use handleRequest
.
You should use submit
directly instead along with the clearMissing
parameter set to false.
Symfony/Component/Form/FormInterface
/**
* Submits data to the form, transforms and validates it.
*
* @param null|string|array $submittedData The submitted data.
* @param bool $clearMissing Whether to set fields to NULL
* when they are missing in the
* submitted data.
*
* @return FormInterface The form instance
*
* @throws Exception\AlreadySubmittedException If the form has already been submitted.
*/
public function submit($submittedData, $clearMissing = true);
When you use handleRequest
it works out what data you are wanting the submit and then submits it using $form->submit($data, 'PATCH' !== $method);
, meaning that unless you have submitted the form using the PATCH
method then it will clear the fields.
To submit the form yourself without clearing your can use...
$form->submit($request->get($form->getName()), false);
.. which get the form data array from the request and submit it directly, but with the clear missing fields parameter set to false.
If your entity has different states, you could reflect this in your form type.
Either create multiple form types (maybe using inheritance) containing the different field setups and instantiate the required one in your controller.
Something like this:
class YourState1FormType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('someField')
;
}
}
class YourState2FormType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('someOtherField')
;
}
}
Or pass a parameter to the single form type upon creation in the controller and adapt the field setup depending on the state. If you don't add the fields that are not present, they don't get processed.
Something like this:
class YourFormType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options)
{
if($options['state'] == 'state1') {
$builder
->add('someField')
;
} else if($options['state'] == 'state2') {
$builder
->add('someOtherField')
;
}
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'state' => 'state1'
));
}
}
Update
Another approach you can take to modify your form based on the submitted data is to register event listeners to the form's PRE_SET_DATA and POST_SUBMIT events. These listeners get called at different moments within the form submission process and allow you to modify your form depending on the data object passed to the form type upon form creation (PRE_SET_DATA) or the form data submitted by the user (POST_SUBMIT).
You can find an explanation and examples in the docs.