4

I have an image field which is optional. When you upload image, it will save the filename on the database (using events via doctrine ).

The problem is when you edit an already uploaded form and don't add an image, it makes the image field to null.

Is there a way to check / remove the field value setting to null if no image is uploaded?

The Entity, Form code is as below :

class Product
{

    /**
     * @ORM\Column(type="string", nullable=true)
     *
     * @Assert\Image
     */
    private $image;
}

Form

class ProductType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('image', FileType::class, [
            'required' => !$options['update'],
        ]);

        $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            $form = $event->getForm();
            $product = $event->getData();

            if (null == $form->get('image')->getData()) {
                // $form->remove('image');
            }
        });
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Product'
        ));
    }

    public function getBlockPrefix()
    {
        return 'appbundle_product';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setRequired([
            'update',
        ]);
    }
}

// In controller

$editForm = $this->createForm(
    'AppBundle\Form\ProductType', 
    $product, 
    [
        'update' => true
    ]
);

2 Answers 2

2

You need the event PRE_SUBMIT, try this:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('image', FileType::class, [
        'required' => !$options['update'],
    ]);

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
        $form = $event->getForm();
        $product = $event->getData();

        if(empty($product['image'])){
            //No new image for existing field was given. Make field disabled so doctrine will not update with empty
            $config = $event->getForm()->get('image')->getConfig();
            $options = $config->getOptions();
            $event->getForm()->add(
                'image',
                $config->getType()->getName(),
                array_replace(
                    $options,
                    ['disabled' => true]
                )
            );
        }
    });
}
Sign up to request clarification or add additional context in comments.

1 Comment

For the record : Instead of $config->getType->getName() ( 2.x ) use get_class($config->getType()->getInnerType()) in 3.x
2

Symfony Form has submit() method, which takes two arguments, $submittedData and $clearMissing

/**
 * 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);

$clearMissing parameter is by the default set to true.

If you, in your controller do this: $form->submit($submittedData, false);, your image will not be set to null.

https://symfony.com/doc/current/form/direct_submit.html#calling-form-submit-manually

Similar question: Symfony2 - How to stop Form->handleRequest from nulling fields that don't exist in post data

3 Comments

Thank you for pointing to the other question / answer. Somehow I missed to see it on my search criteria. I also like some of the comments also regarding files handling there. Somehow the data is missing when a file is uploaded. I may want to try more where the error is. Just pointing out.
This clearMissing flag was just what I was looking for !
I spent hours trying to understand why the attributes that were not sent into the PATCH payload were changed to false! Adding false as a second argument to the submit did fix it. So always add false for PATCH submits.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.