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.
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
Hi, thank you for the feedback. I’ve updated the code.
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];
}
++
Thank you for the feedback, code is updated :)
Hi,
Nice code! I try it, it works but I need update your constructor by updating sfWidgetSchema in sfWidgetFormSchema.
Hope it helps
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 !
Thanks for the feedback. I have updated the code to use sfWidgetFormSchema instead of sfWidgetSchema.
Well done !
@Antoine
Thanks :)
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.