Symfony 1.2 sfForm formatter to add stars on required fields
The following is a form formatter class I developed to automatically add stars * on required fields. Feel free to use it and let me know if it can be improved.
You might ask, why not just use setLabels?
Firstly, if you already set required fields to true/false in setValidators, why do you have to add the stars manually again in setLabels? It just doesn't make sense!
Secondly, using setLabels to add stars is interfering with language translation.
Thirdly, this is I believe a proper (or proper-ish?) way to do this kind of things with sfForm.
OK, let's get into it!
Below is an example on how to use it in your form class
<?php class yourForm extends sfForm { function configure() { $this->setWidgets(array( 'first_name' => new sfWidgetFormInput(array(), array('maxlength' => 50)), 'last_name' => new sfWidgetFormInput(array(), array('maxlength' => 50)), 'email' => new sfWidgetFormInput(array(), array('maxlength' => 128)), )); $this->setValidators(array( 'first_name' => new sfValidatorString(array('max_length' => 50, 'required' => true)), 'last_name' => new sfValidatorString(array('max_length' => 50, 'required' => false)), 'email' => new sfValidatorEmail(array('max_length' => 128, 'required' => true)), )); $decorator = new sidFormFormatter($this->widgetSchema, $this->validatorSchema); $this->widgetSchema->addFormFormatter('custom', $decorator); $this->widgetSchema->setFormFormatterName('custom'); } }
This is optional but you might want to add the following into your css (e.g.: main.css)
em.required {font-size:1.2em;font-weight:bold;margin:0px;padding:0px;} label.required {font-weight:bold;}
Last but most importantly, save this formatter class in your project lib folder as sidFormFormatter.php:
<?php class sidFormFormatter extends sfWidgetFormSchemaFormatter { protected $rowFormat = "\n%error%\n<div class=\"formRow\">\n<div class=\"formLabel\">%label%</div>\n<div class=\"formField\">%field%\n%help%</div></div>\n%hidden_fields%", $helpFormat = '<div class="fieldHelp">%help%</div>', $errorRowFormat = "<div>\n%errors%<br /></div>\n", $errorListFormatInARow = "<ul>%errors%</ul>\n", $errorRowFormatInARow = "<li class=\"error\">↓ %error% ↓</li>\n", $namedErrorRowFormatInARow = "<li class=\"error\">↓ %error% ↓</li>\n", $decoratorFormat = "%content%"; /** * @var sfValidatorSchema */ protected $validatorSchema = null; /** * @var array */ protected $params = array(); /** * Constructor * * Params: * - "required_label_class_name" css class name for label tag when the field is required field, the default is 'required'. * - "required_label_format" default is '%label% <em class="required">*</em>'. * * @param sfWidgetFormSchema $widgetSchema * @param sfValidatorSchema $validatorSchema * @param array $params */ public function __construct(sfWidgetFormSchema $widgetSchema, sfValidatorSchema $validatorSchema, $params = array()) { $this->validatorSchema = $validatorSchema; $this->params = $params; parent::__construct($widgetSchema); } /** * Returns parameter identified with $name or if does not exist, returns $default. * * @param string $name * @param mixed $default * @return mixed */ public function getParameter($name, $default=null) { if (!isset($this->params[$name])) { return $default; } return $this->params[$name]; } /** * Generates a label for the given field name. * * @param string $name The field name * @param array $attributes Optional html attributes for the label tag * * @return string The label tag */ public function generateLabel($name, $attributes = array()) { $is_required = false; if ( $this->validatorSchema and isset($this->validatorSchema[$name]) ) { $validator = $this->validatorSchema[$name]; /* @var $validator sfValidatorBase */ if ( $validator->getOption('required') ) { $class_name = $this->getParameter('required_label_class_name', 'required'); if (isset($attributes['class'])) $attributes['class'] .= ' '.$class_name; else $attributes['class'] = $class_name; $is_required = true; } } $s = parent::generateLabel($name, $attributes); if ($is_required) { $format = $this->getParameter('required_label_format', '%label% <em class="required">*</em>'); $s = str_replace('%label%', $s, $format); } return $s; } }
That's it! Don't forget to "symfony cc" (clear cache).
Happy coding!
No related posts.
Related posts brought to you by Yet Another Related Posts Plugin.
August 31st, 2009 - 01:31
Nice code, perhaps could you make the “required” class configurable by passing options to the constructor, and do not replace $attributes['class'] by “required” concaten it, make the “*” configurable too
August 31st, 2009 - 02:04
Hi, thank you for the feedback. I’ve updated the code.
August 31st, 2009 - 04:49
Thanks for sharing this. Your getParameter() method can be shorted as below to gain in readability :
public function getParameter($name, $default=null)
{
if (!isset($this->params[$name]))
{
return $default;
}
return $this->params[$name];
}
++
August 31st, 2009 - 10:06
Thank you for the feedback, code is updated :)
September 1st, 2009 - 22:32
Hi,
Nice code! I try it, it works but I need update your constructor by updating sfWidgetSchema in sfWidgetFormSchema.
Hope it helps
September 7th, 2009 - 13:34
I agree with TIM. I also struggled a bit with the code but after changing the sfWidgetSchema tosfWidgetFormSchema in the Constructor, everything worked perfectly and oh so elegantly ! :)
Thanks for the code !
September 7th, 2009 - 13:44
Thanks for the feedback. I have updated the code to use sfWidgetFormSchema instead of sfWidgetSchema.
November 16th, 2009 - 15:14
Well done !
January 19th, 2010 - 00:06
@Antoine
Thanks :)
February 24th, 2010 - 17:13
Just wondering if there was some way in the Form class to just add specific row formatting for 1 or 2 elements as this is unique to just this form, instead of having to create an entire decorator class to handle it.
May 10th, 2011 - 02:35
Hi ! nice snippet ! thank you very much !
November 26th, 2011 - 01:44
tks for the snippet!! from Argentina