Symfony 2 forms validation

Featured Image

sxc.hu/bredmaker

NOTE: Tested on Symfony2 PR12. Might not work on later releases!

To continue previous article when writing about forms in Symfony 2, now it’s time to write something about forms validation.

In the previous article, we created a form like this:

<?php
//Surgeworks/AdminBundle/Forms/LanguageForm.php
namespace Surgeworks\AdminBundle\Forms;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\TextField;
use Symfony\Component\Form\HiddenField;
//form for Create and update information about languages
class LanguageForm extends Form{
    protected function configure() {
        $this->add(new TextField('language_name',  array('max_length'=>50, 'required' => true)));
        $this->add(new TextField('language_symbol',  array('max_length'=>10, 'required' => true)));
        $this->addOption('name', 'adminForm');
    }
}

Now we need to validate these two fields for entering new record into database when form is submitted. This is done by creating new file called ‘validation.yml’. Of course you have more possibility to create that file like the other configuration files either in xml or plain php. But for purposes of article let’s make it in yaml.

//Surgeworks/AdminBundle/Resources/config/validation.yml
Surgeworks\AdminBundle\Entity\Language:  //enter name of your entity to validate against
    properties:
        language_name:
            - NotBlank: { message: "Language name field can not be empty!" }
        language_symbol:
            - NotBlank: { message: "Language symbol field can not be empty!" }

After all ‘hard work’ is done, let’s tell to our controller action to validate that form:
(Using same controller from last article)

//…
    public function addAction() {
	//Creating form's instance
        $form = LanguageForm::create($this->get('form.context'), 'adminForm');
//...
//Binding form to entity...
$form->bind($request, $language);
//...
	//If our form passes validation
            if ($form->isValid()) {
	    //We already made bind to entity, just need to save data into database
                $em->persist($language);
                $em->flush();
	 //Now it's time to redirect to some url when data is saved...
                return new RedirectResponse($this->generateUrl('_admin_languages'));
}
//...

Of course, until now, I didn’t mention:
what about AJAX?
If we send form’s data in some AJAX form, can we validate this way?

There is also solution for AJAX too:

First we need to determine type of request received in our controller:

//...
$request = $this->get('Request');
            $isAjax = $request->isXmlHttpRequest();//if true – then AJAX is used
//..

Now when we know is that AJAX request we could write AJAX validation handling part:

//Our controller file
/* BEGIN If is ajax call... */
            if ($isAjax == true) {
                $validator = $this->container->get('validator');
                $errorList = $validator->validate($language);
                $msg = "";
                if (count($errorList) > 0) {
                    foreach ($errorList as $err) {
                        $msg.= $err->getMessage() . "\n";
                    }
                    $code = "ERR";
                } else {
                    $em->persist($language);
                    $em->flush();
                    $msg = "Language saved successfully!";
                    $code = "OK";
                }
                $response = new Response(json_encode(array('code' => $code, 'msg' => $msg)));
                $response->headers->set('Content-Type', 'application/json');
                return $response;
            }

Let me explain what I did here: First of all, we get validator service, and then get list of errors if any by validating our Entity instance with validator service. (variable ‘$language’ is our entity instance).

Then we loop through possible errors and adding error message to variable $msg. Also, I predefined two possible response messages for AJAX response: “ERR” and “OK” and I am handling it in my AJAX function on the client side. So, when return $code and $message are defined depends if we have errors or not, let’s just return response to our AJAX function in JSON form for easy processing with our Javascript on client side. (We shouldn’t forget to set response headers to application/json).

To all of these get work, we need to do one more thing:

framework:
    validation:    { enabled: true, annotations: false }

Add, or check if exists this into your main config.yml file of application and also make sure if you are using validation this way, that annotations are false. If you are using annotations for validation, don’t forget to set it to true here.

This is all for now. BTW, yesterday I looked in official documentation and find out that will be some new ways, let’s say different ways for using forms in project in first beta release of Symfony 2, and when that release is available to me, I will write more about forms in new way of handling it.

2
Top

Care to rate this post?

Author

Darko Goles

Ex Inchooer

Darko worked at Inchoo as Backend Developer from March 2011 to January 2014

Other posts from this author

Discussion 2 Comments

Add Comment
  1. hackle

    hi man,

    this is very interesting. but as i experiment according to this post, i does not work – validation does not take effect. whatever i submit it always goes through.

    also the form class doesnt work either, error is no ::create() function. i dug into the component form.php and could not find it, maybe we downloaded different versions?

  2. Your code samples are all screwed up. You have HTML entities instead of greater-than signs and NON-BREAKING SPACES for indentation!

Add Your Comment

Please wrap all source codes with [code][/code] tags.
Top