4

I have a search form with 2 fields, not linked to an entity. Let's say it's built like this:

$builder
    ->add('orderNumber', 'text', array('required' => false))
    ->add('customerNumber', 'text', array('required' => false))
    ;

I want the users to be obliged to fill at least one of the two fields.

What is the proper way to achieve this with Symfony 2.5?

Edit: Can it be done without adding a data class?

Gregoire
  • 3,735
  • 3
  • 25
  • 37
  • 1
    possible duplicate of [With Symfony2 how can I get the form validator to require at least one of a set of fields?](http://stackoverflow.com/questions/9844112/with-symfony2-how-can-i-get-the-form-validator-to-require-at-least-one-of-a-set) – sjagr Oct 14 '14 at 15:19
  • @sjagr It's not exactly the same, since my form is not linked to an entity – Gregoire Oct 14 '14 at 15:20
  • Except it's still achievable and proper with a validation constraint and/or callback constraint since it doesn't belong to Symfony's default set of validation constraints. – sjagr Oct 14 '14 at 15:25
  • As far as I know, the constraints have to be applied on the entity, and can't be used in a form without entity. – Gregoire Oct 14 '14 at 15:32

2 Answers2

8

Thanks to @redbirdo answer, I result in this code:

$builder
    ->add('orderNumber', 'text', array(
        'required' => false,
        'constraints' => new Callback(array($this, 'validate'))
    ))
    ->add('customerNumber', 'text', array('required' => false))
;

And the validate method is:

public function validate($value, ExecutionContextInterface $context)
{
    /** @var \Symfony\Component\Form\Form $form */
    $form = $context->getRoot();
    $data = $form->getData();

    if (null === $data['orderNumber'] && null === $data['customerNumber']) {
        $context->buildViolation('Please enter at least an order number or a customer number')
            ->addViolation();
    }
}
Gregoire
  • 3,735
  • 3
  • 25
  • 37
3

When you are using a form with an array of data rather than an underlying data class, you need to set up the validation constraints yourself, and attach them to the individual fields. See the Symfony Documentation:

Forms -> Using a form without a class -> Adding Validation

For example

$builder
   ->add('orderNumber', 'text', array(
       'required' => false
       'constraints' => new NotBlank()
   ))
   ->add('customerNumber', 'text', array(
       'required' => false
       'constraints' => new NotBlank()
   ))
;

Note - according to the documentation example, 'constraints' may be provided as a single constraint or an array of constraints.

redbirdo
  • 4,937
  • 1
  • 30
  • 34
  • Thank you for your answer, it helped me to find the solution. I post the final code in a new answer. – Gregoire Oct 15 '14 at 07:46