分かりづらいタイトルですが、SymfonyのFormというコンポーネントに関する話です。
HTMLフォームの表示やバリデーションを行うコンポーネントなのですが、これを使うと簡単にラジオボタンの選択ができます。
例えば。
うん、悪くないです。でも…
クレジットカードと銀行振込、それぞれに必要な入力欄を一緒に表示するにはどうしたらいいでしょう?要するに、ラジオボタンを任意の場所に表示して、こんなフォームを作りたいのです。
インストールなど
確認したのは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
を指定した上にexpanded
にtrue
を指定します。
普通にフォームを表示
せっかくなので、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 %}
これだけで、すごくきれいなフォームを表示してくれます。
慣れれば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 %}
すると…
ちょっとHTMLは複雑ですが、狙い通りになりました。