symfony 1.4では、フォームのオプションを介してフォームクラス定義をパラメーター化することが可能でした。カスタムオプションをカスタムフォームタイプに渡す方法はありますか?私はbuildForm
メソッドのoptionsパラメータを使用しようとしましたが、この配列が何であるかよくわかりません。どうやらそれは私が望むものではないようです...ありがとう!
解決策は簡単です。カスタムオプションをTwigテンプレートでも利用可能にする場合は、buildForm
メソッドで$builder->setAttribute()
を使用し、$view->set()
メソッドもbuildView()
メソッドで。
<?php
namespace Acme\DemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType as FormAbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
// For Symfony 2.1 and higher:
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
/**
* ImagePreviewType
*
*/
class ImagePreviewType extends FormAbstractType
{
/**
* {@inheritDoc}
* For Symfony 2.0
*/
//public function getDefaultOptions(array $options)
//{
// $options = parent::getDefaultOptions($options);
// $options['base_path'] = 'path/to/default/dir/';
//
// return $options;
//}
/**
* {@inheritDoc}
* For Symfony 2.1 and higher
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'base_path' => '',
));
}
/**
* {@inheritDoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
// For Symfony 2.0:
// $view->set('base_path', $form->getAttribute('base_path'));
// For Symfony 2.1 and higher:
$view->vars['base_path'] = $options['base_path'];
}
/**
* {@inheritDoc}
*/
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->setAttribute('base_path', $options['base_path'])
;
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'image_preview';
}
public function getParent(array $options)
{
// for Symfony 2.0:
// return 'field';
// for Symfony 2.1 and higher:
return 'form';
}
}
カスタムフォームタイプのテンプレート(ファイル... Acme/DemoBundle/Resources/views/Form/fields.html.twig):
{% block image_preview_widget %}
{% spaceless %}
<img src="{{ base_path ~ value }}" alt="" {{ block('widget_container_attributes') }} />
{% endspaceless %}
{% endblock %}
カスタムフォームタイプのテンプレートをapp/config/config.ymlに登録します
twig:
debug: %kernel.debug%
strict_variables: %kernel.debug%
form:
resources:
- 'AcmeDemoAdminBundle:Form:fields.html.twig'
使用法:ユーザーのプロファイルの編集中にユーザーの画像のプレビューを表示します。
// src/Acme/DemoBundle/Form/Type/UserType.php
namespace Acme\DemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class UserType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('user_profile_image_file_name', new ImagePreviewType(), array(
'base_path' => 'some/other/dir',
));
}
}
2014-08-18:Symfony 2.1以降用に更新
PDATE:このソリューションは、廃止されたSymfony 2.0.xでのみ機能することに注意してください。setDefaultOptions
の代わりにgetDefaultOptions
を使用してください。
当然、Symfony 2のフォームタイプは、フォームタイプ内で必要なものに使用できるオプションを受け入れます。タイプオプションを指定するには、getDefaultOptions
メソッドをオーバーライドする必要があります。
たとえば、my_option
を受け入れるMyCustomType
型があり、このオプションのデフォルト値はfalse
です。MyCustomType
の実装は次のようになります。
class MyCustomType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
if($options['my_option']){
//do something
} else {
//do another thing
}
...
}
public function getDefaultOptions(array $options)
{
return array(
'my_option' => false
);
}
public function getName()
{
return 'mycustomtype';
}
}
後で、コントローラーでフォームを作成するときに、buildForm
の3番目のパラメーターを使用してオプションを指定する必要があります。
$form = $this->buildForm(new MyCustomType(), null, array(
'my_option' => true
));
my_option
オプションを指定しない場合、デフォルト値(false
)が使用されます。
Symfony 2.8を使用して、configureOptions()
メソッドを拡張する提案されたソリューションを使用することに成功しました。
_class ElementType extends AbstractType
{
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'my_custom_option_parameter' => null,
));
}
}
_
コレクションと埋め込みフォームとしてElementType
を使用する必要がありました。 CollectionType
のconfigureOptions()
をカスタマイズしなかったが、CollectionType
をカスタマイズしていないため、_my_custom_option_parameter
_をElementType
に渡すことができないことを認識しました。 CollectionType
を介して_my_custom_option_parameter
_を渡す必要がある場合は、_my_custom_option_parameter
_で_entry_options
_を定義することで成功する場合があります(ドキュメント CollectionType Field )CollectionType
の配列。
CollectionType
を介して_my_custom_option_parameter
_を渡す例:
_class OuterFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//...
$builder->add('elements', CollectionType::class, array(
'entry_type' => ElementType::class,
// ...
'entry_options' => array(
'my_custom_option_parameter' => 'value is now set!'
)
));
//...
}
}
_
@pulzarraiderの回答に基づいて、Symfony 3用に変更を加えたコードを作成しました。
変更する必要があります
OptionsResolverInterface
for OptionsResolver
FormBuilder
for FormBuilderInterface
私の場合:
namespace MediaBundle\Form;
use Symfony\Component\Form\AbstractType as FormAbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
class ImageType extends FormAbstractType {
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'max_images' => ''
));
}
public function buildView(FormView $view, FormInterface $form, array $options) {
$view->vars['max_images'] = $options['max_images'];
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->setAttribute('max_images', $options['max_images'])
;
}
public function getName() {
return 'image_preview';
}
public function getParent() {
return TextareaType::class;
}
}
Symfony 3を使用して、フォームタイプクラスのconfigureOptionsメソッドに挿入されたOptionsResolverでデフォルトオプションを設定することで、カスタムオプションをフォームに渡すことができました。
コントローラーで:
_//Compile whatever your options are here. Assume an array is returned
$customOptions = $this->getMyCustomOptions($args);
//Build the form:
$form = $this->createForm(MyCustomFormType::class, array('my_custom_options' => $customOptions));
_
MyCustomFormType.php:
_public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => DataModel::class,
'my_custom_options' => []
]);
}
//custom options is now set in "$options" array:
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('my_custom_fields', Type\ChoiceType::class, [
'choices' => $options['my_custom_options'],
'mapped' => false //if not part of the data model.
. . .
_
したがって、フォームとデータプロバイダーとのコントラクトを定義して、フォームに任意のデータを設定できるようです。
この手順を正常に実装しました。復路では、formBuilderで_'mapped' => false,
_を設定しているため、$form->getData()
は選択を返しません。選択した値を取得するには:
_$mySelectedValue = $form->get('my_custom_options')->getViewData();
_
コントローラーで。なぜこれが私の向こうにあるのか。 。 。
私はそのオプションarray
を使用しようとしましたが、キーの事前定義された小さなサブセットのみを運ぶことができると思われたため、成功しませんでした。これはどうしても私には受け入れられませんでした...
ただし、フォーム__construct
メソッドを介してすべてのオプションを渡し、後で使用するためにクラスプロパティに保存することができます。次に、buildForm
から$this->"propertyName"
...を使用してアクセスできます。
__construct
に単一のarray
を渡すか、いくつかの変数を渡すかを決めるのはあなた次第です...
これは大まかな例です。
class Foobar{
private $update = false;
public function __construct($update = false){
$this->update = $update;
}
public function buildForm(FormBuilder builder, array options){
if ( $update ){
// something
}else{
// well, this is not an update - do something else
}
}
}