【问题标题】:How to disable specific item in form choice type?如何禁用表单选择类型中的特定项目?
【发布时间】:2012-12-29 23:01:07
【问题描述】:

我有一个表单,其中包含数据库中实体的选择字段:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('categories', 'document', array(
        'class' => 'Acme\DemoBundle\Document\Category',
        'property' => 'name',
        'multiple' => true,
        'expanded' => true,
        'empty_value' => false
    ));
}

此表单将生成复选框列表,并将呈现为:

[ ] Category 1
[ ] Category 2
[ ] Category 3

我想按值禁用此列表中的某些项目,但我不知道我应该在哪里拦截选择字段项目来执行此操作。

有人知道解决办法吗?

【问题讨论】:

  • 你想让它们变灰还是一开始就不显示?
  • 我刚刚发现可以在finishView 中直观地禁用它们。仍然要澄清如何防止在 setData 期间更改禁用值。

标签: symfony symfony-forms


【解决方案1】:

只需使用 finishViewPRE_BIND 事件监听器处理它。

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('categories', 'document', array(
        'class' => 'Acme\DemoBundle\Document\Category',
        'property' => 'name',
        'multiple' => true,
        'expanded' => true,
        'empty_value' => false
    ));

    $builder->addEventListener(FormEvents::PRE_BIND, function (FormEvent $event) {
        if (!$ids = $this->getNonEmptyCategoryIds()) {
            return;
        }

        $data = $event->getData();

        if (!isset($data['categories'])) {
            $data['categories'] = $ids;
        } else {
            $data['categories'] = array_unique(array_merge($data['categories'], $ids));
        }

        $event->setData($data);
    });
}

...

public function finishView(FormView $view, FormInterface $form, array $options)
{
    if (!$ids = $this->getNonEmptyCategoryIds()) {
        return;
    }

    foreach ($view->children['categories']->children as $category) {
        if (in_array($category->vars['value'], $ids, true)) {
            $category->vars['attr']['disabled'] = 'disabled';
            $category->vars['checked'] = true;
        }
    }
}

【讨论】:

  • 这帮助我摆脱了困境。谢谢。
  • sf 2.3.* 有什么变化?因为这个解决方案对我不起作用。
  • 这是不安全的,因为(如果 html 被操纵)仍然可以选择。
  • 这篇文章包含两种不同的方法来禁用复选框。我花了一个小时才得到这个。对我来说,finishView 方法的第二种方法更容易使用。
【解决方案2】:

您可以在$form->add() 中使用'choice_attr' 并传递一个函数,该函数将根据选择的值、键或索引决定是否添加disabled 属性。

...
    'choice_attr' => function($key, $val, $index) {
        $disabled = false;

        // set disabled to true based on the value, key or index of the choice...

        return $disabled ? ['disabled' => 'disabled'] : [];
    },
...

【讨论】:

  • 这个解决方案有什么问题?恕我直言,这是正确的做法,请参阅:symfony.com/doc/current/reference/forms/types/…
  • @DavidKmenta 不适用于 Symfony 2.7 之前的版本
  • 请记住,有些用户可以使用浏览器检查器删除 disabled 属性!所以你必须添加更多指令......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-14
  • 2016-09-27
  • 1970-01-01
  • 1970-01-01
  • 2018-03-01
  • 2021-10-06
相关资源
最近更新 更多