2

In my form I have two datetime fields: startDate and endDate. startDate can't be earlier than current time. endDate cant be earlier or equal to the startDate and it can't be more than one month from the startDate.

So my question is how I could implement validation for those fields? I'm pretty new to Symfony so I would really appreciate if you could add and example of it.

My form:

<?php
namespace Atotrukis\MainBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Validator\Constraints as Assert;
class CreateEventFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text', [
                'constraints' =>[
                    new Assert\NotBlank([
                        'message' => "Renginio pavadinimas negali būti tuščias"
                    ]),
                    new Assert\Length([
                        'min' => "2",
                        'max' => "255",
                        'minMessage' => "Renginio pavadinimas negali būti trumpesnis nei {{ limit }} simboliai",
                        'maxMessage' => "Renginio pavadinimas negali būti ilgesnis nei {{ limit }} simboliai"
                    ])
                ]
            ])
            ->add('description', 'textarea', [
                'constraints' =>[
                    new Assert\NotBlank([
                        'message' => "Renginio aprašymas negali būti tuščias"
                    ]),
                    new Assert\Length([
                        'min' => "10",
                        'max' => "5000",
                        'minMessage' => "Renginio aprašymas negali būti trumpesnis nei {{ limit }} simbolių",
                        'maxMessage' => "Renginio aprašymas negali būti ilgesnis nei {{ limit }} simbolių"
                    ])
                ]
            ])
            ->add('startDate', 'datetime')
            ->add('endDate', 'datetime')
            ->add('map', 'text')
            ->add('city', 'entity', array(
                'class' => 'AtotrukisMainBundle:City',
                'property' => 'name',
                'constraints' =>[
                    new Assert\NotBlank([
                        'message' => "Pasirinkite miestą"
                    ])
                ],
                'empty_value' => 'Pasirinkite miestą',
                'query_builder' => function(EntityRepository $er) {
                    return $er->createQueryBuilder('c')
                        ->addOrderBy('c.priority', 'ASC')
                        ->addOrderBy('c.name', 'ASC');
                },
            ))
            ->add('save', 'submit', array('label' => 'Sukurti'));
    }
    public function getName()
    {
        return 'createEventForm';
    }
}

2 Answers 2

1

I can think of two ways you can acchive what you ask.

First way is Create a Class Constraint Validator. You can follow my answer on a similar question here and the chapter on the sf2 documentation here

Second way is to make use of Callback Constraint. For example in you CreateEventFormType class:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'constraints'=> 
              array(new Callback(array('methods'=>array(array($this, 'customFormValidation'))))),
    ));
}

public function customFormValidation($data, ExecutionContextInterface $context)
{
    if ($data['startDate'] && $data['endDate'] && $data['startDate'] > $data['endDate']) {
        $context->addViolationAt('startDate', 'your constraint message here');
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

SF3/Silex2 update (I know the question is for SF2) this code is for Silex but the only differences are the builder factory function and the render stuff.

    $form = $app->namedForm('form', $data, [
        'constraints' => array(
            new Callback(function ($data, ExecutionContextInterface $context) {
                if ($data['to'] && $data['from'] && $data['to'] < $data['from']) {
           $context->buildViolation('error')->addViolation();
                }
            }),
        ),
    ])
        ->add('from', DateType::class)
        ->add('to', DateType::class)
        ->add('save', SubmitType::class)
        ->getForm();

    $form->handleRequest($request);

    if ($form->isSubmitted()) {

        if ($form->isValid()) {
            // your submit stuff
            return $app->redirect($request->getUri());
        }
        // error validation does not dispay errors after a redirect
    }

    return $app['twig']->render('form.html.twig', [
        'form' => $form->createView(),
    ]);

Comments

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.