当Symfony发现您的表单无效时,它会再次显示该表单,但会为验证失败的每个元素添加错误。错误基本上只是无序列表:
<label>First Name</label>
<ul class='error-list'>
<li>Required.</li>
</ul>
<input type='text' name='first_name'/>
我正在试图弄清楚是否有某种方法可以强制Symfony将自定义类添加到验证失败时我想要的任何元素。例如,当验证失败时,将class='error'
添加到label
或input
。这样我就可以设计这些元素。
我开始查看表单架构装饰器,但乍一看似乎没有办法做到这一点。但我可能是错的。
无论如何要做到这一点?
答案 0 :(得分:2)
如果您的应用需要启用javascript,那么最简单,更灵活的方法是使用javascript动态地通过某些类/属性。例如,你可以有这样的脚本
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');
});
}
});
如果您确实不需要依赖启用javascript,那么您选择使用自定义格式化程序。以下是一个例子。
/**
* 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;
}
}
要为所有表单启用自定义格式化程序,请使用ProjectConfiguration类进行设置。
// /config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
public function setup()
{
/// CODE FOR ENABLING PLUGINS...
// configure your default form formatter
sfWidgetFormSchema::setDefaultFormFormatterName('custom');
}
}
答案 1 :(得分:2)
我找到了另一个使用hasError()方法的解决方案。
<?php if ($form['email']->hasError()) {
echo $form['email']->render( array('class'=>'error') );
} else {
echo $form['email']->render();
} ?>
hasError()
显然会检查该表单元素是否有错误。
答案 2 :(得分:0)
您可以全局覆盖form_label块,而不是将条件应用于每个表单字段:
{%- block form_row -%}
<div>
{{- form_label(form) -}}
{{- form_widget(form) -}}
</div>
{%- endblock form_row -%}
{%- block form_label -%}
{% if label is not sameas(false) -%}
{% if not compound -%}
{% set label_attr = label_attr|merge({'for': id}) %}
{%- endif %}
{% if required -%}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{%- endif %}
{% if label is empty -%}
{%- if label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{%- endif -%}
{% if errors|length > 0 %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' error_class')|trim}) %}
{% endif %}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>{{ label|trans({}, translation_domain) }}</label>
{%- endif -%}
{%- endblock form_label -%}
在你的配置中:
twig:
form:
resources:
- 'Form/fields.html.twig'