これは古いスレッドだと思いますが、他の人が役立つと思った場合に備えて、別の解決策を提供したいと思いました。私は3つのことをしたかったので、このトピックに関する他の回答に満足していませんでした。
- 各ビューテンプレートでカスタムフォームレンダリングを行う必要はありません(私は単に使用するのが好きです
{{ form(form) }}
)
- キャンセルボタンを送信ボタンのすぐ隣に表示します(カスタムレンダリングを行わない場合、symfonyはデフォルトですべてのフォームボタンをdivタグでラップするため、驚くほど注意が必要です)
- 追加するか編集するかなどでリンクが変わるので、コントローラーのオプションとしてキャンセルアクションを設定できます。
そして、私はDRYの原則を適用しながらこれらすべてをやりたかったのです。まず、基本フォームタイプを拡張して、カスタムオプション'cancel_action'を許可しました。
<?php
namespace AcmeBundle\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FormTypeExtension extends AbstractTypeExtension
{
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
parent::configureOptions($resolver);
$resolver->setDefined('cancel_action');
$resolver->setAllowedTypes('cancel_action', 'string');
}
/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
parent::buildView($view, $form, $options);
if (isset($options['cancel_action'])) {
$view->vars['cancel_action'] = $options['cancel_action'];
}
}
/**
* {@inheritdoc}
*/
public function getExtendedType()
{
return 'form';
}
}
そして、そのフォームタイプ拡張を私の設定に登録しました(エイリアス'form'を使用して、すべてのフォームで使用できるようにします):
acme.form_type_extension:
class: AcmeBundle\Form\Extension\FormTypeExtension
tags:
- {name: form.type_extension, alias: form}
次に、フォームテーマを使用してベースフォームビューを拡張しました(submit_widgetブロックを拡張して、キャンセルボタンがdivタグ内の送信ボタンの横に表示されるようにしました)。
{# AcmeBundle:Form:fields.html.twig #}
{% extends 'form_div_layout.html.twig' %}
{%- block submit_widget -%}
{%- set type = type|default('submit') -%}
{{ block('button_widget') }}
{% if form.parent.vars.cancel_action is defined %}
<a class="btn btn-default" href="{{ form.parent.vars.cancel_action }}" role="button">Cancel</a>
{% endif %}
{%- endblock submit_widget -%}
そして、そのフォームテーマを私の小枝構成に登録して、デフォルトですべてのフォームビューに適用されるようにしました。
twig:
form_themes:
- 'AcmeBundle:Form:fields.html.twig'
出来上がり!ここで、フォームごとに、キャンセルボタンが必要な場合は、コントローラーでフォームを初期化するときに、オプションとしてキャンセルアクションを指定するだけです。
$form = $this->createForm(new AlbumType(), $album, array(
'cancel_action' => $this->generateUrl('album_home')
));