🎻

[Symfony/Form] 継承元のFromTypeの項目のオプションを部分的に変更する方法

2020/12/03に公開

Symfony Advent Calendar 2020 の3日目の記事です!🎄🌙小ネタですみません!

昨日も僕の記事で、[Symfony][Doctrine] COUNT()やCONCAT()の結果でORDER BYする方法 でした✨

ちなみに、僕はよく TwitterにもSymfonyネタを呟いている ので、よろしければぜひ フォローしてやってください🕊🤲

あと、この記事とよく似た内容の以下のような記事もあるので、よろしければあわせてご参照ください🤲
[Symfony/Form] 子FormTypeの特定の項目をそのユースケースでのみ必須にする方法

やりたいこと

例えば、以下のように BaseType を継承して FooType を作り、項目を1つ追加してその項目に autofocus をつけたとします。

class FooType extends BaseType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);

        $builder
            ->add('additionalField', TextType::class, [
                'label' => 'ほげほげ',
                'attr' => [
                    'autofocus' => true,
                ],
            ])
        ;
    }
}

このとき、 BaseType が持っている項目にすでに autofocus がついていたとしたら、実際の挙動としては(ブラウザの実装依存かもしれませんが)あとにレンダリングされたほうの項目にフォーカスが当たることになります。

意図としては additionalField が確実にフォーカスされてほしいので、 BaseType 側の項目の autofocus を外したいですよね。

こういう場合の対処方法について説明します。

やり方

やり方はすごく簡単で、

  1. $builder->get(フィールド名)->getOptions() で変更したいフィールドのオプションを取得
  2. オプションの内容を部分的に変更
  3. $builder->add() し直す

だけです👍

class FooType extends BaseType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        parent::buildForm($builder, $options);

        $builder
            ->add('additionalField', TextType::class, [
                'label' => 'ほげほげ',
                'attr' => [
                    'autofocus' => true,
                ],
            ])
        ;

        // 既存項目のオプションを部分的に変更してaddし直す
        $fieldOptions = $builder->get('existentField')->getOptions();
        $fieldOptions['attr']['autofocus'] = false;
        $builder->add('existentField', TextType::class, $fieldOptions);
    }
}

親の autofocus を外すというケース以外でも覚えておくと役に立つかもしれません。

以上です!

Symfony Advent Calendar 2020、明日は @77web さんです!お楽しみに!

GitHubで編集を提案

Discussion