Symfony:在验证失败时为表单元素添加自定义类?

时间:2011-08-03 19:38:17

标签: php symfony1

当Symfony发现您的表单无效时,它会再次显示该表单,但会为验证失败的每个元素添加错误。错误基本上只是无序列表:

<label>First Name</label>
<ul class='error-list'>
  <li>Required.</li>
</ul>
<input type='text' name='first_name'/>

我正在试图弄清楚是否有某种方法可以强制Symfony将自定义类添加到验证失败时我想要的任何元素。例如,当验证失败时,将class='error'添加到labelinput。这样我就可以设计这些元素。

我开始查看表单架构装饰器,但乍一看似乎没有办法做到这一点。但我可能是错的。

无论如何要做到这一点?

3 个答案:

答案 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'