【问题标题】:Symfony2 change field options of an embedded formSymfony2 更改嵌入式表单的字段选项
【发布时间】:2012-07-21 22:33:52
【问题描述】:

我的问题基本上是,是否可以从父表单更改嵌入字段的选项?

为了说明问题考虑这个;我有一个像这样的父表单类型类:

class FruitFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('apple', new AppleFormType())
        ;
    }

和一个单独的包中的子表单类型类,我不想编辑,像这样:

class AppleFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('qty', 'integer', array('label' => 'rubbish label')
        ;
    }

我想将qty 的标签更改为其他内容,但我只想在FruitForm 中执行此操作,而不是在使用AppleForm 的任何地方。我曾希望能够做类似的事情:

class FruitFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('apple', new AppleFormType(), array('qty' => array('label' => 'better label')))
        ;
    }

或:

class FruitFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text')
            ->add('apple', new AppleFormType())
        ;

        $builder->get('apple')->get('qty')->setOption('label', 'better label');
    }

但这些(以及其他一些尝试)都没有让我失望。我可以看到不存在setOption 方法。

有人知道这样做的方法吗?

谢谢

【问题讨论】:

    标签: forms symfony option


    【解决方案1】:

    我还想更改选项,即 FOSUserBundle 中现有字段的明显“更改标签”案例。我知道我可以在 Twig 或翻译中做到这一点。

    @redbirdo 用“似乎添加同名字段将替换它”为我指明了正确的方向。这是解决方案:

    $field = $builder->get('username');         // get the field
    $options = $field->getOptions();            // get the options
    $type = $field->getType()->getName();       // get the name of the type
    $options['label'] = "Login Name";           // change the label
    $builder->add('username', $type, $options); // replace the field
    

    【讨论】:

    • $options = $field->getOptions();对我不起作用,但是, $field->getConfig()->getOptions() 成功了!再次感谢!
    • 对我来说效果很好。 @Steven 您需要使用 $form->get("field")->getOptions(),否则该名称的字段尚不存在。
    • 作为细节,我使用的是 Symfony 4,并且 $type = $field->getType()->getName();不起作用,(getName 未定义)。我必须这样做: $type = get_class($field->getType()->getInnerType());如果有人有更好的主意,我完全赞成。
    【解决方案2】:

    非常感谢@Peter Wooster。 在 Symfony 3.0 中,我不得不使用一些不同的东西:

    我有一个自定义表单类型,添加如下字段:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('my_field', ChoiceType::class, [
            // Some options here...
            'multiple' => false,
        ]);
    }
    

    在另一个自定义表单类型中,我需要扩展上面的类型并更改一些选项:

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);
    
        $myField = $builder->get('my_field');
        $fieldOptions = $myField->getOptions();
        // Retrieve the FormType. That is the part that is different.
        $fieldType = get_class($myField->getType()->getInnerType());
        $fieldOptions['multiple'] = true;
        // I can obviously put the name 'my_field' directly here
        $builder->add($myField->getName(), $fieldType, $fieldOptions);
    }
    

    感谢以上回答,希望对我有所帮助!

    【讨论】:

      【解决方案3】:

      试试这样的:

      class AppleFormType extends AbstractType
      {
          public function buildForm(FormBuilderInterface $builder, array $options)
          {
              $builder
                  ->add('name', 'text')
                  ->add('qty', 'integer', array('label' => $options['qtyLabel'])
              ;
          }
      
          public function getDefaultOptions()
          {
              return array(
                  'qtyLabel' = 'rubbish label';
              );
          }
      }
      

      和:

      class FruitFormType extends AbstractType
      {
          public function buildForm(FormBuilderInterface $builder, array $options)
          {
              $builder
                  ->add('name', 'text')
                  ->add('apple', new AppleFormType(), array('qtyLabel' => 'better label'))
              ;
          }
      }
      

      【讨论】:

      • 感谢您的回答,我知道这是一个选项,但由于 AppleFormType 在供应商捆绑中,我必须覆盖或替换才能使其正常工作。我希望有一个可以完全在 FruitFormType 类中完成的解决方案。
      • 抱歉,我看到您不想编辑它,但假设您可以覆盖它。像 $builder->get('apple')->add('qty', 'integer', array('label' => 'better label') 这样的东西是一种选择吗?从阅读 FormBuilder 的 (2.0) 文档似乎添加一个具有相同名称的字段将替换它,但显然你必须重新定义所有选项,而不仅仅是标签......
      • 已编辑 - 我找到了 FormBuilderInterface 的 API。它确实有 get/setAttribute()。您是否尝试过使用 $builder->get('apple')->get('qty')->setAttribute('label', 'better label');?
      • 是的,那将是理想的,但不幸的是,“标签”是一个选项,而不是一个属性。我之前尝试过,我只是再次测试以更加确定(仍然没有做任何事情)。我现在开始使用覆盖方法。我喜欢您在上面的评论中建议的->add 方法,正如您所说,它有其缺点,但是建议的最简单的方法(+1 ;))
      • 更好的方法
      【解决方案4】:

      我无法访问表单构建器代码但必须覆盖字段选项以添加'required' => true

      扩展 @peter-wooster 和 @thedamnedrhino 对 github 上的 symfony 问题 (https://github.com/symfony/symfony/issues/11188) 的回复,我最终得到了这段代码。

      $field = $form->get('combinaisons');
      $options = $field->getConfig()->getOptions();
      $type = $field->getConfig()->getType()->getName();
      $options['required'] = true;
      unset($options['em']);
      $form->add('combinaisons', $type, $options); 
      

      这适用于 symfony/symfony:2.3.21、教义/doctrine-bundle:1.2.0 和教义/orm:2.3.6

      【讨论】:

        【解决方案5】:

        对于这种更改,修改视图通常要容易得多。

        $view->vars['label'] = 'New label';
        

        通常您的视图将是一个父表单,因此它可能看起来像这样 - 从“日期”>“发布日期”更改:

        $view = $form->createView(...);
        $view->children['date']->vars['label'] = 'Publication date';
        

        如果你的表单被封装成自己的类型,你可以使用 finishView 函数:

        public function finishView(FormView $view, FormInterface $form, array $options)
        {
            $view->children['date']->vars['label'] = 'Publication date';
        }
        

        由于最终传递给模板引擎进行渲染的大部分内容都是直接数组形式,因此此时您可能会弄乱很多东西。

        【讨论】:

        • 请注意,此更改仅适用于“当前”视图。这不会改变构建视图的形式。但我希望这个解决方案适合许多用例。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-20
        相关资源
        最近更新 更多