Einius
Einius

Reputation: 1382

Symfony2 form datetime fields validation

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';
    }
}

Upvotes: 2

Views: 1309

Answers (2)

quazardous
quazardous

Reputation: 876

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(),
    ]);

Upvotes: 0

Jo&#227;o Alves
Jo&#227;o Alves

Reputation: 1941

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');
    }
}

Upvotes: 1

Related Questions