Build-in symfony form validation is really great feature. Using Propel or Doctrine ORM we have simple validation by default which we can modify in simple way.
But sometimes we want something more than server side validation (later in post SSV) and then we can easliy use javascript. Client side validation (CSV) is nice and useful but we need to remember that it could be easily switched off. So SSV is always required.
Let’s begin.
I’m not going to build a whole application. I just want to show you how to create simple contact form, validate it using SSV and CSV (with jQuery) and save it.
First of all we need to create new symfony app. If we have symfony already installed on our PC, we can just create new project directory, for example sfSimpleApp and then call:
<?php
symfomy generate:project sfSimpleApp
?>
Remember that you need to write symfony tasks in command line (on windows -cmd prompt).
As it is a simple example we are not going to configure a web server.
If We don’t have symfony - it’s not a problem - download Symfony 1.2 sandbox.
Then generate standard frontend app and contact module:
<?php
symfony generate:app frontend
symfony generate:module frontend contact
?>
Now we can configure our database:
<?php
symfony configure:database "mysql:host=localhost;dbname=sfSimpleApp" user password
?>
In our example we need just one table - to store our contacts. The follwing schema is just what we need:
propel:
contact:
id: ~
name: { type: varchar(255), required: true }
email: { type: varchar(255), required: true }
subject: { type: varchar(255), required: true }
message: { type: longvarchar, required: true }
No it’s time for symfony. First, we will generate and insert sql:
<?php
symfony propel:build-sql
symfony propel:insert-sql
?>
then models and forms:
<?php
symfony propel:build-model
symfony propel:insert-forms
?>
Now we can start coding but not to much:) Open our actions file from contact module.
Paste the follwoing code:
<?php
class contactActions extends sfActions
{
public function executeIndex(sfWebRequest $request)
{
/* create new contact Form */
$this->form = new ContactForm();
/* handle Post request */
if($request->isMethod('post') &amp;&amp; $request->hasParameter('contact')) {
/* bind, validate and save form */
$this->form->bind( $request->getParameter('contact') );
if( $this->form->isValid() ){
/* saving data */
$this->form->save();
$this->success = true;
}
}
}
}
?>
Then in template file indexSuccess.php we can put something like that:
<div class="contactForm">
<h1>Contact Form </h1>
<?php if( isset($success) ): ?>
<div class="success_message">
You message was successfully saved;
</div>
<?php endif; ?>
<?php if ($form->hasErrors()): ?>
<div class="error_message">
Sorry, but there are some erros. Please, check yor form again.
</div>
<?php endif; ?>
<?php echo $form->renderFormTag(url_for('contact/index'), array('id' => 'contactForm')) ?>
<table>
<?php echo $form ?>
<tr>
<td colspan="2"> <input type="submit" value="Send Message" /> </td>
</tr>
</table>
</form>
</div>
You can customize your form as you want. More information about that you can find on Symfony Form documentation.
We can also add some css style to our project for better look (to web/js/main.css).
.contactForm {
width: 550px;
margin: 75px auto;
}
.success_message {
background: PaleGreen;
list-style: none;
border: 1px solid green;
padding: 5px;
width: 500px;
}
.error_message {
background: Pink;
list-style: none;
border: 1px solid red;
padding: 2px;
width: 500px;
}
label.error {
background: pink;
border: 1px solid red;
display: block;
}
.error_list {
background: pink;
border: 1px solid red;
list-style: none;
width: 200px;
}
Default validation usually is not enough. So we need to open lib/form/contactForm.class.php and put this code in configure method:
<?php
/* You can add validation to other fields in the same way */
$this->validatorSchema['name']->addMessage('required', 'Your name is required.');
/* We have to change default string validator to e-mail Validator */
$this->validatorSchema['email'] = new sfValidatorEmail(array(), array(
'invalid' => 'Invalid Email Format'));
/* We can also change default labels */
$this->widgetSchema->setLabels(
array(
'name' => 'Name and Surname',
'email' => 'Your e-mail'
)
);
?>
You can try it now on http://localhost/sfSimpleApp/web/contact. Try to submit form - should see something like that:

As far we have nice form that is working really well. But we want more. It’s time to add javascript validation to our form. We will use jquery plugin: Validation that can be downloaded from project site. Put jquery code into web/js/jquery/ directory. You can add that scripts in diffrent ways but i prefer to use yml files:
frontend/config/view.yml
default:
http_metas:
content-type: text/html
metas:
title: contact Form
#description: symfony project
#keywords: symfony, project
#language: en
robots: index, follow
stylesheets: [main.css]
javascripts: [ jquery/jquery-1.2.6.js, jquery/jquery.validate.js ]
has_layout: on
layout: layout
And everything would be ok execpt that the validation plugn won’t work with our symfony contact form. The problem is that this plugin is adding validation to each filed by its name. When we are using sfForm defualt naming standard is
<input type="text" name="contact[subject]" id="contact_subbject" />
Name is diferreny from id. All we have to do is to simply modify validation library (change from name to id in some functions). Don’t worry i have done it already ( i’m not javascript expert but i tested it and it’s working fine for me) - if you know any reasons for which i should not modify that library in this way - write a comment. My changed version.
Ok. After that we have to add the follwoing code at the end of indexSuccess.php file (it’s our jquery validation):
<script type="text/javascript">
$('document').ready(function(){
validateContactForm();
});
function validateContactForm() {
var $validator = $("#contactForm").validate({
/*validation rules */
rules: {
contact_name: "required",
contact_subject: "required",
contact_email: {
required: true,
email: true
},
contact_message: "required"
},
messages: {
contact_name: 'This field is required',
contact_subject: 'This field is required',
contact_email: {
required: 'This field is required',
email: 'Invalid e-mail format'
},
contact_message: 'This field is required'
},
errorPlacement: function(error, element) {
/* Error placement */
error.insertBefore( element );
}
});
}
</script>
We should also move that that function to other file.
Our javascript validation in action:

That’s all. It’s really worth to spent some time on jquery plugin validation documentation - nice, simple and really useful.
It would be more interesting if the jquery code could be generated automatically from the symfony one… Does not seem to be a hard task but will definitely be something worth of great interest!
I prefer using jquery validation plugin as i showed above. I think it would be hard to take control of this plugin and its all features integrating (auto-generating) it with symfony code. But if you want you can check it here: http://shout.setfive.com/2009/01/23/client-side-validation-for-the-new-symfony-forms-with-jquery/
Thanks for the informative article, I am going to try the methods you have discussed.
What about a little bit of abstraction ?
I add this few line in the setup function of the BaseFormPropel and all my project form will be converted to an Ajax Form ,
$sfRequest = sfContext::getInstance()->getRequest() ;
if($sfRequest->isMethod(’post’) || $sfRequest->isMethod(’put’)){
$this->bind($sfRequest->getParameter($this->widgetSchema->getNameFormat()));
if($sfRequest->isXmlHttpRequest()){
if (!$this->isValid()) {
$js = ” ;
foreach ($this->getErrorSchema() as $field => $error) {
$js .=’jQuery(document).ready(function() {’ ;
$js .= ‘var field = \” . $field . ‘\’;’ ;
$js .= ‘$( field.replace(\’%s\’,\” . $this->widgetSchema->getNameFormat() . ‘\’) ).insertBefore(\” . $error . ‘\’) ;’ ;
$js .=’}) ;’ ;
}
$this->js = $js ;
}else{
$this->js = ‘var formState = 1 ;’ ;
}
}
}
and i parse the js variable in the form template like this :
echo $sf_data->getRaw(’js’);
Cordialy Ahmed .
I’ve got a problem seeing your site properly in the latest release of Opera. It’s fine in IE7 and Firefox however.
A chum recommended me to look at this page, great post, interesting read… keep up the good work!
Is this working with sf 1.4? Someone have already tested using same code replacement as Kamil?
Yes, this code should also work properly with Symfony 1.4.
I found your site on technorati and read a few of your other posts. Keep up the good work. I just added your RSS feed to my Google News Reader. Looking forward to reading more from you down the road!
Many people like to know when they comment that someone is listening. The way to let them know that there is someone behind the computer screen who cares what they say is to respond when they say something.
If you wanted to just leave a backlink - it is not the right place. MODERATED!
, in line 37 is wrong. must be removed.
line 29 typo found, enail instead of email.
Thanks, you’re right. This will not work with IE.
FIXED.
Very good primer on the subject and should help many businesses better understand SEO. I will be recommending it.
Congratulations for posting such a useful blog. Your blog is not only informative but also very artistic too. There usually are very few individuals who can write not so easy articles that creatively. Keep up the good writing !!
They are inspiring and very helpful.Many thanks for sharing your info and stories.