【问题标题】:Symfony 3 - Forms choices: How to set 'disabled' = true on "placeholder"Symfony 3 - 表单选择:如何在“占位符”上设置 'disabled' = true
【发布时间】:2016-05-06 09:30:23
【问题描述】:

在 Symfony 3 中,我希望选择列表菜单的“占位符”在进行任何选择之前出现,但不出现(或不可选择)在用户的可用选项列表中。

MyEntityType 的函数 buildForm(),扩展 AbstractType 如下所示:

public function buildForm(FormBuilderInterface $builder, array $options)
  {

    $list = array([array with choices values and descriptions]);
    $builder
    ->add('description',TextType::class, array('label'=>'trans.my_desc'))
  ->add('list',ChoiceType::class,array(
    'label'=>'trans.my_list',
    'multiple'=>false,
    'choices'=>$list,
    'placeholder'=>'trans.do_a_choice',
    //'placeholder_in_choices'=>false //this option is not available
)
->add('submit',SubmitType::class,array('label'=>'trans.validate'));

  }

当我查看文档时,我看到有一个布尔选项 placeholder_in_choices (http://symfony.com/doc/current/reference/forms/types/choice.html#field-variables) 但无法在“->add('list' ,ChoiceType::class,array([array of options for list])"(它会引发错误,说明 'placeholder_in_choices' 不是可用选项)。

通过我的搜索,我发现这个已经存在的问题与我很接近:Symfony how to disable the default option

通读之后,我尝试在 MyEntityType 类中实现 finishView() 函数:

 public function finishView(FormView $view, FormInterface $form, array $options){

    var_dump($view->children['list']->vars);

   foreach ($view->children['list']->vars['choices'] as $sma) {
        if ($sma->value == "") {
            $sma->attr['disabled'] = 'disabled';
        }
   }
}

问题在于,正如 var_dump() 中所示,$view->children['list']->vars['choices'] 不包括 'placeholder' 值或标签(trans.do_a_choice ),因此不可能将“禁用”属性附加到它。

是否有人知道如何让“trans.do_a_choice”在选择菜单中显示为占位符,但在选项列表中不出现(或不可选择)?

【问题讨论】:

  • 只需确保在现场将 required 设置为 true 即可?那么当表单设置了占位符设置时,会抛出错误,因为没有设置任何值...
  • 我不确定我是否理解。您想要一个占位符显示,然后一旦用户单击下拉菜单,就会消失?如果是这样的话,那听起来更像是一个前端 (JS) 任务。
  • @LMS94 如果我在选择菜单中选择“trans.do_a_choice”,则
  • @Francesco Abeni,我不希望它一定会消失,我希望用户无法选择它(因此将
  • 如果你想要做的是this,那么提供 disabled 属性的 Symfony 会很麻烦。我会为这样的任务使用 javascript,如果用户没有 javascript,表单验证将阻止发布默认值。

标签: symfony-forms symfony


【解决方案1】:

我目前正在使用 Symfony 4.4 并试图找到解决问题的方法。

解决方案 1:扩展默认 Symfony 表单模板

此选项似乎不可用,因此如果您严格想要此结果,一种方法是通过将disabled="disabled" 添加到占位符选项标签来覆盖默认的form_div_layout.html.twig 表单模板。

为此,您需要在项目中创建templates/form/form_div_layout.html.twig(更新在第 8 行)。

{% extends 'form_div_layout.html.twig' %}
{%- block choice_widget_collapsed -%}
    {%- if required and placeholder is none and not placeholder_in_choices and not multiple and (attr.size is not defined or attr.size <= 1) -%}
        {% set required = false %}
    {%- endif -%}
    <select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
        {%- if placeholder is not none -%}
            <option value=""{% if required and value is empty %} selected="selected" disabled="disabled"{% endif %}>{{ placeholder != '' ? (translation_domain is same as(false) ? placeholder : placeholder|trans({}, translation_domain)) }}</option>
        {%- endif -%}
        {%- if preferred_choices|length > 0 -%}
            {% set options = preferred_choices %}
            {% set render_preferred_choices = true %}
            {{- block('choice_widget_options') -}}
            {%- if choices|length > 0 and separator is not none -%}
                <option disabled="disabled">{{ separator }}</option>
            {%- endif -%}
        {%- endif -%}
        {%- set options = choices -%}
        {%- set render_preferred_choices = false -%}
        {{- block('choice_widget_options') -}}
    </select>
{%- endblock choice_widget_collapsed -%}

解决方案 2:使用纯 CSS 解决方法

纯 css 解决方案是一种解决方法,可在打开列表时从列表中删除占位符选项。 原代码来自How to create a placeholder for an HTML5 box

select:required:invalid {
  color: #666;
}

select:required option[value=""] {
  display: none;
}

option {
  color: #000;
}
<select name="drinks" required>
  <option value="" disabled selected>Choose a drink</option>
  <option value="coffee">Coffee</option>
  <option value="tea">Tea</option>
  <option value="milk">Milk</option>
</select>

【讨论】:

    【解决方案2】:

    您必须覆盖表单的主题,或至少覆盖choice_widget_collapsed 块。如果使用默认的form_div_layout,则相关部分如下所示:

    {%- if placeholder is not none -%}
        <option value=""{% if required and value is empty %} selected="selected"{% endif %}>{{ placeholder != '' ? (translation_domain is same as(false) ? placeholder : placeholder|trans({}, translation_domain)) }}</option>
    {%- endif -%}
    

    在这里,您可以将 disabled 属性放在选项或任何其他属性上。可悲的是choice_attr 或任何其他选项都不适用于占位符,所以这是我认为的唯一方法。

    有关表单主题的更多信息: http://symfony.com/doc/current/form/form_customization.html

    【讨论】:

      【解决方案3】:

      如果我理解正确,您希望占位符存在但不被接受为选定值?

      为此,只需添加一个选择约束,您就会获得所需的行为。如果用户选择空值或占位符值,表单将不会通过验证。

      类似这样的:

         use Symfony\Component\Validator\Constraints as Assert;
      
         public function buildForm(FormBuilderInterface $builder, array $options)
            {
      
              $list = array([array with choices values and descriptions]);
              $builder
              ->add('description',TextType::class, array('label'=>'trans.my_desc'))
            ->add('list',ChoiceType::class,array(
              'label'=>'trans.my_list',
              'multiple'=>false,
              'choices'=>$list,
              'placeholder'=>'trans.do_a_choice',
              'constraints' => array(
                                  new Assert\Choice($valuesFromTheListOfChoices)
                              ),
          )
          ->add('submit',SubmitType::class,array('label'=>'trans.validate'));
      
            }
      

      非常重要的是,在断言/选择中传递的值与选择列表中的值相匹配。这意味着如果您选择占位符值,则必须得到验证错误。

      对于“placeholder_in_choices”,该选项是根据“placeholder”、“choices”或“preferred_choices”解析的。

      https://github.com/symfony/form/blob/3.1/Extension/Core/Type/ChoiceType.php#L204

      如果您的选择列表中有一个值为空的项目,它将设置为 true。

      【讨论】:

        猜你喜欢
        • 2020-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-22
        • 2012-04-07
        • 2016-10-12
        相关资源
        最近更新 更多