Reputation: 1388
Let's say we have a Symfony2 form containing 3 checkboxes (A, B, C) and we want the user to tick at least one checkbox in order to validate the form, so any combination ([A], [B], [C], [A,B], [A,C], [B,C] ,[A,B,C]) would return true and no selection [] returns false.
What is the right approach to achieve this using Symfony validators on Doctrine objects?
Edit:
Each checkbox is mapped to it's own column in the database using Doctrine @ORM\Column(type="boolean")
Upvotes: 1
Views: 1956
Reputation: 1796
We can use the Expression
constraint:
namespace App\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints as Assert;
class MyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('myFirstCheckbox', CheckboxType::class, [
'required'=> false,
])
->add('mySecondCheckbox', CheckboxType::class, [
'required'=> false,
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'constraints' => new Assert\Expression(
expression: 'this.get("myFirstCheckbox").getData() or this.get("mySecondCheckbox").getData()',
message: 'Please choose 1 of the 2 checkboxes.',
)
]);
}
}
Upvotes: 0
Reputation: 1388
Problem solved.
Based on Symfony2 Class Constraint Validator documentation and on Added info on changes to setting validation subpath to UPGRADE-2.1.md
In my entity class I've added:
class Message
{
// ...
// check if user selected at least one network to publish the message
public function isNetworkSelected(ExecutionContext $context)
{
if (!$this->network_twitter && !$this->network_facebook && !$this->network_googleplus)
{
$context->addViolationAtSubPath('network_facebook', 'Please select at least one network', array(), null);
}
}
// ...
}
In validation.yml
:
MY\MessageBundle\Entity\Message
constraints:
- Callback:
methods: [isNetworkSelected]
Upvotes: 1
Reputation: 4923
If you're correctly using the choice field type for your list of options, you can use ChoiceValidator
:
@Assert\Choice(min=1, minMessage = "You must choose at least one option.")
From the docs:
If the multiple option is true, then you can use the min option to force at least XX number of values to be selected. For example, if min is 3, but the input array only contains 2 valid items, the validation will fail.
Upvotes: 3
Reputation: 555
Do you have a button control? If so, on the click event, check if there is a selection made if so, return true, else return false.
Upvotes: 0