When Symfony finds that your form is invalid, it shows it again but with the addition of errors for each element that failed validation. The errors are basically just unordered lists:
<label>First Name</label>
<ul class='error-list'>
<li>Required.</li>
</ul>
<input type='text' name='first_name'/>
I'm trying to figure out if there is some way to force Symfony to also add custom classes to whatever elements I want when they fail validation. For example add a class='error'
to my label
or input
when the validation fails. That way I can style those elements.
I started looking at form schema decorators but at first glance it doesn't seem like there is a way to do it. But I could be wrong.
Is there anyway to accomplish this?
If your app requires javascript to be enabled, then the easiest and more flexible way to go is to use javascript to through in some classes/attributes dynamically. For example, you could have a script like this
jQuery(document).ready(function($){
if($('.sf_admin_form .error_list').length>0 ){ // style if erro is present
$('.sf_admin_form .error_list').each(function(){
// label of fields with error should be bold and red
$(this).prev('label').css('font-weight', 'bold');
$(this).prev('label').css('color', 'red');
});
}
});
If you do need not count on javascript being enabled, than your choice is use a custom form formatter. The following is an example.
/**
* Class derived from Table formatter, renders customized version if the row has errors.
*
* @package symfony
* @subpackage widget
* @author Paulo R. Ribeiro <paulo@duocriativa.com.br>
*/
class sfWidgetFormSchemaFormatterCustom extends sfWidgetFormSchemaFormatter
{
protected
$rowFormat = "<tr>\n <th>%label%</th>\n <td>%error%%field%%help%%hidden_fields%</td>\n</tr>\n",
// THIS IS NEW
$rowWithErrorsFormat = "<tr class='has-errors'>\n <th class='has-errors'>%label%</th>\n <td class='has-errors'>%error%%field%%help%%hidden_fields%</td>\n</tr>\n",
//
$errorRowFormat = "<tr><td colspan=\"2\">\n%errors%</td></tr>\n",
$helpFormat = '<br />%help%',
$decoratorFormat = "<table>\n %content%</table>";
$errorListFormatInARow = " <ul class=\"error_list\">\n%errors% </ul>\n",
$errorRowFormatInARow = " <li>%error%</li>\n",
$namedErrorRowFormatInARow = " <li>%name%: %error%</li>\n",
public function formatRow($label, $field, $errors = array(), $help = '', $hiddenFields = null)
{
if(count($erros)==0){ // no errors, renders as usual
return strtr($this->getRowFormat(), array(
'%label%' => $label,
'%field%' => $field,
'%error%' => $this->formatErrorsForRow($errors),
'%help%' => $this->formatHelp($help),
'%hidden_fields%' => null === $hiddenFields ? '%hidden_fields%' : $hiddenFields,
));
} else { // has errors, through in some classes
return strtr($this->getRowWithErrorsFormat(), array(
'%label%' => $label,
'%field%' => $field,
'%error%' => $this->formatErrorsForRow($errors),
'%help%' => $this->formatHelp($help),
'%hidden_fields%' => null === $hiddenFields ? '%hidden_fields%' : $hiddenFields,
));
}
}
public function getRowWithErrorsFormat()
{
return $this->rowWithErrorsFormat;
}
}
To enabled the custom formatter for all the forms, use the ProjectConfiguration class to set it up.
// /config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
/// CODE FOR ENABLING PLUGINS...
// configure your default form formatter
sfWidgetFormSchema::setDefaultFormFormatterName('custom');
}
}