PHP
RadioButton
Symfony4

Symfony/FormコンポーネントのChoiceTypeのラジオボタンをバラバラに表示する方法

分かりづらいタイトルですが、SymfonyのFormというコンポーネントに関する話です。

HTMLフォームの表示やバリデーションを行うコンポーネントなのですが、これを使うと簡単にラジオボタンの選択ができます。

例えば。

支払い方法1

うん、悪くないです。でも…

クレジットカードと銀行振込、それぞれに必要な入力欄を一緒に表示するにはどうしたらいいでしょう?要するに、ラジオボタンを任意の場所に表示して、こんなフォームを作りたいのです。

支払い方法2

インストールなど

確認したのはSymfonyのVersion 4.1。

まずはSymfonyのインストール

composer create-project symfony/website-skeleton sym-radio-test

フォームオブジェクトの作成

まずはControllerでフォームオブジェクトを作成してみます。

class ChoiceController extends Controller
{
    /**
     * @Route("")
     */
    public function form(): Response
    {
        $form = $this->createFormBuilder()
            ->add('payment', ChoiceType::class, [
                'choices'  => [
                    'クレジットカード'   => 'credit',
                    '銀行振込' => 'bank',
                ],
                'expanded' => true,
                'label' => '支払い方法',
            ])
            ->add('credit', TextType::class, [
                'label' => 'カード番号',
            ])
            ->add('bank', TextType::class, [
                'label' => '振込人名義',
            ])
            ->getForm();
        return $this->render("form.html.twig", [
            'form' => $form->createView(),
        ]);
    }
}

paymentがラジオボタンになります。ChoiceType::classを指定した上にexpandedtrueを指定します。

普通にフォームを表示

せっかくなので、bootstrapレイアウトを利用してみます。

{% extends("base.html.twig") %}

{% form_theme form 'bootstrap_4_horizontal_layout.html.twig' %}

{% block body %}
    <h1>支払い方法</h1>

    <p class="text-info">クレジットカードを選択したらカード番号を、銀行振込を選択したら振込人名義を記入してください。</p>
    {{ form_start(form) }}
    {{ form_widget(form) }}
    <input type="submit" class="btn btn-primary" value="enter" />
    {{ form_end(form) }}

{% endblock %}

これだけで、すごくきれいなフォームを表示してくれます。

form1.png

慣れればSymfony/Formは非常に簡単に綺麗なフォームを作れると思う。

ラジオボタンを任意の位置に表示してみる

フォーム表示が簡単にできるのはいいけれど、どこまで自由度があるかも大事。最初のフォームの場合なら、クレジットカードや銀行振込に関するフォームは、それぞれまとめて表示してみます。

実はラジオボタンは配列になっていて、

{{ form_widget(form.payment[0] }}

とすることでpaymentの各ラジオボタンを表示できます。

これを利用して、先のHTMLフォームを工夫してみます…

{% extends("base.html.twig") %}

{% form_theme form 'bootstrap_4_horizontal_layout.html.twig' %}

{% block body %}
    <h1>支払い方法2</h1>

    <p class="text-primary">クレジットカードか銀行振込を選択してください。</p>

    {{ form_start(form) }}
    <div class="row form-group">
        <div class="col-sm-12">
            <span class="text-info">クレジットカードを選択したら、カード番号を記入してください。</span>
            {{ form_widget(form.payment[0]) }}
            {{ form_row(form.credit) }}
        </div>
    </div>
    <div class="row">
        <div class="col-sm-12">
            <span class="text-info">銀行振込を選択したら、振込人名義を記入してください。</span>
            {{ form_widget(form.payment[1]) }}
            {{ form_row(form.bank) }}
        </div>
    </div>
    <input type="submit" class="btn btn-primary" value="enter" />
    {{ form_end(form) }}

{% endblock %}    

すると…

支払い方法2

ちょっとHTMLは複雑ですが、狙い通りになりました。