Dan
Dan

Reputation: 6553

Form validation - Require only one field to be filled in

I have the following form class:

public function buildForm(FormBuilderInterface $builder, array $options)
{
        $builder
            ->add('existingfolder', 'entity', array(
                'class'     => 'ImageBundle:Folder',
                'required'  => false,
            ))
            ->add('folder', 'text', array('required' => false))
            ->add('file', 'file');
}

How can I set up the validation so that either the existingfolder or folder field must be filled (but not both of them)?

Any advice appreciated.

Thanks.

Upvotes: 1

Views: 3434

Answers (1)

Sybio
Sybio

Reputation: 8645

Use the True or Callback validation assert, here an example to check if the user must give at least one of the folders:

<?php
namespace Acme\BlogBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;

class Image
{
    // ...properties, functions, etc...

    /**
     * @Assert\True(message = "You must give at least an existing folder or a new folder")
     */
    public function isThereOneFieldFilled()
    {
        return ($this->existingfolder || $this->folder); // If false, display an error !
    }
}

Here another example if the user must give ONLY one field but not both:

    /**
     * @Assert\True(message = "You must give an existing folder or a new folder, not both")
     */
    public function isThereOnlyOneFieldFilled()
    {
        return (!$this->existingfolder && $this->folder || $this->existingfolder && !$this->folder);
    }

EDIT:

Callback validation inside a form (I found an example here):

// use ...
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormInterface;

// Inside the form:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('existingfolder', 'entity', array(
            'class'     => 'ImageBundle:Folder',
            'required'  => false,
        ))
        ->add('folder', 'text', array('required' => false))
        ->add('file', 'file');

    // Use the CallbackValidator like a TrueValidator behavior
    $builder->addValidator(new CallbackValidator(function(FormInterface $form) {
        if (!$form["existingfolder"]->getData() && !$form["folder"]->getData()) {
            $form->addError(new FormError('You must give at least an existing folder or a new folder'));
        }
    }));
}

Upvotes: 8

Related Questions