web-dev-qa-db-ja.com

Symfony2のフォームフィールドにデフォルト値を設定する方法は?

テキストフォームフィールドのデフォルト値を設定する簡単な方法はありますか?

131
Ondrej Slinták

作成中に簡単に使用できます:

->add('myfield', 'text', array(
     'label' => 'Field',
     'data' => 'Default value'
))
99
webda2l

empty_dataでデフォルト値を設定できます

$builder->add('myField', 'number', ['empty_data' => 'Default value'])
114
rkmax

私は過去にこれを数回考えましたので、私が持っていた/使用したさまざまなアイデアを書き留めると思いました。何か役に立つかもしれませんが、どれも「完璧な」Symfony2ソリューションではありません。

Constructorエンティティで$ this-> setBar( 'default value');を実行できます。しかし、これはエンティティ(dbであるかどうかに関係なく)を読み込むたびに呼び出され、少し面倒です。ただし、日付など必要なものを作成できるため、すべてのフィールドタイプで機能します。

get内のステートメントの場合しませんが、できます。

return ( ! $this->hasFoo() ) ? 'default' : $this->foo;

工場/インスタンス。データが事前に入力されたデフォルトのエンティティを提供する静的関数/セカンダリクラスを呼び出します。例えば。

function getFactory() {
    $obj = new static();
    $obj->setBar('foo');
    $obj->setFoo('bar');

   return $obj;
}

余分なフィールドを追加する場合、この機能を維持する必要があるため、理想的ではありませんが、データセッター/デフォルトとデータベースから生成されるデータセッターを分離していることを意味します。同様に、異なるデフォルトデータが必要な場合は、複数のgetFactoriesを使用できます。

拡張/リフレクションエンティティ拡張コンストラクタを作成します(例:FooCreateはFooを拡張します)。これにより、作成時にデフォルトのデータが提供されます(コンストラクタを介して)。 Factory /インスタンスのアイデアと同様に、異なるアプローチ-私は静的メソッドを個人的に好みます。

フォームをビルドする前にデータを設定するコンストラクター/サービスで、新しいエンティティーがあるか、データベースから取り込まれたかがわかります。したがって、新しいエンティティを取得するときに、さまざまなフィールドのセットデータを呼び出すのが妥当です。例えば。

if( ! $entity->isFromDB() ) {
     $entity->setBar('default');
     $entity->setDate( date('Y-m-d');
     ...
}
$form = $this->createForm(...)

フォームイベントフォームを作成するとき、フィールドを作成するときにデフォルトデータを設定します。この使用PreSetDataイベントリスナーをオーバーライドします。これに伴う問題は、フォームのワークロードを複製し、コードを複製し、保守や理解を難しくしていることです。

拡張フォームフォームイベントに似ていますが、db /新しいエンティティであるかどうかに応じて異なるタイプを呼び出します。つまり、編集フォームを定義するFooTypeがあり、BarTypeはFooType thisを拡張し、すべてのデータをフィールドに設定します。コントローラで、扇動するフォームタイプを選択するだけです。ただし、カスタムテーマがあり、イベントが好きな場合は、これが気に入らず、私の好みにはあまりにも多くのメンテナンスが作成されます。

Twigフィールドごとに独自のテーマを作成し、valueオプションを使用してデータをデフォルトに設定できます。テンプレートをきれいに保ち、フォームを再利用できるようにする場合でも、これをフォームテーマにラップすることを止めるものはありません。例えば.

form_widget(form.foo, {attr: { value : default } });

JSフィールドが空の場合、フォームにJS関数を入力するのは簡単です。たとえば、プレースホルダーを使用して何かを行うことができます。しかしこれは悪い、悪い考えです。

サービスとしてのフォーム私がやった大きなフォームベースのプロジェクトの1つについて、すべてのフォームを生成し、すべての処理を行うサービスを作成しました。これは、フォームが複数のコントローラーで使用されるためです。複数の環境で、フォームが同じ方法で生成/処理されている間、それらは異なる方法で表示/操作されます(たとえば、エラー処理、リダイレクトなど)。このアプローチの利点は、データのデフォルト設定、必要なすべての操作、一般的なエラー処理などが可能で、すべてが1か所にカプセル化されていることです。

結論私が見るように、あなたは何度も同じ問題に出くわします-デフォルトのデータはどこにありますか?

  • Db/doctrineレベルで保存する場合、毎回デフォルトを保存したくない場合はどうなりますか?
  • エンティティレベルで保存すると、そのエンティティをデータなしで他の場所で再利用したい場合はどうなりますか?
  • エンティティレベルで保存して新しいフィールドを追加する場合、編集時に以前のバージョンにそのデフォルト値を設定しますか? DBのデフォルトについても同様です...
  • フォームレベルで保存する場合、後でコードを保守するときにそのことは明らかですか?
  • コンストラクター内にある場合、フォームを複数の場所で使用するとどうなりますか?
  • あなたがそれをJSレベルにプッシュしたら、あなたは行き​​過ぎです-データはビューにあるべきではありませんJSを気にしないでください
  • 私のように複数の場所で使用している場合、このサービスは素晴らしいですが、1つのサイトで単純な追加/編集フォームを使用するのはやり過ぎです...

そのため、毎回異なる方法で問題に取り組みました。たとえば、サインアップフォームの「ニュースレター」オプションは、フォームを作成する直前にコンストラクターで簡単に(そして論理的に)設定されます。一緒にリンクされたフォームコレクションを作成していたとき(たとえば、異なるフォームタイプのラジオボタンが一緒にリンクされていた場合)、イベントリスナーを使用しました。より複雑なエンティティ(たとえば、子またはデフォルトのデータを大量に必要とするエンティティ)を作成したとき、必要に応じて関数(たとえば 'getFactory')を使用して要素を作成しました。

私はこの要件を持っているたびにそれがわずかに異なっていたので、1つの「正しい」アプローチがあるとは思わない。

がんばろう!とにかく考えのために食べ物を与えて、とりあえずはささやかなかったと思います;)

62
stefancarlton

デフォルト値を設定する必要があり、フォームがエンティティに関連している場合、次のアプローチを使用する必要があります。

// buildForm() method
public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder
    ...
    ->add(
        'myField',
        'text',
        array(
            'data' => isset($options['data']) ? $options['data']->getMyField() : 'my default value'
        )
    );
}

それ以外の場合、myFieldは、エンティティから値を取得する代わりに、常にデフォルト値に設定されます。

42
Dmitriy

モデルクラスの関連フィールドにデフォルトを設定できます(マッピング定義で、または自分で値を設定します)。

さらに、FormBuilderでは setData() メソッドを使用して初期値を設定できます。フォームビルダーは、フォームクラスの createForm() メソッドに渡されます。

また、このリンクを確認してください: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class

19
Jakub Zalas

フォームがエンティティにバインドされている場合は、constructメソッドを使用してエンティティ自体にデフォルト値を設定するだけです。

public function __construct()
{
    $this->field = 'default value';
}
16
Hubert Perron

アプローチ1(from http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/ )から

変数宣言またはコンストラクターで、エンティティにデフォルト値を設定するだけです。

class Entity {
    private $color = '#0000FF';
    ...
}

または

class Entity {
    private $color;

    public function __construct(){
         $this->color = '#0000FF';
         ...
    }
    ...
}

上記のリンクのコメントからのアプローチ2、および Symfony2のフォームフィールドのデフォルト値の設定方法 からのDmitriyの回答(受け入れられたものではありません)

Dmitriyの回答に基づいて、FormBuilderでフィールドを追加するときに、データ属性にデフォルト値を追加します。

これは、プロパティが新しいエンティティであり、既存のエンティティではない場合にのみ値を持つことを想定していることに注意してください。

public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add('color', 'text', array(
            'label' => 'Color:',
            'data' => (isset($options['data']) && $options['data']->getColor() !== null) ? $options['data']->getColor() : '#0000FF'
        )
    );
}
12
crysallus

デフォルト値を設定できます。このようなmessageの形式の場合:

$defaultData = array('message' => 'Type your message here');
$form = $this->createFormBuilder($defaultData)
    ->add('name', 'text')
    ->add('email', 'email')
    ->add('message', 'textarea')
    ->add('send', 'submit')
    ->getForm();

フォームがエンティティにマップされている場合、次のようにできます(例:デフォルトのユーザー名):

$user = new User();
$user->setUsername('John Doe');

$form = $this->createFormBuilder($user)
    ->add('username')
    ->getForm();

主にクラスのないフォームを使用するか、デフォルト値を設定するためにサービスにアクセスする必要がある場合の、あらゆるケース/アプローチの一般的なソリューション:

// src/Form/Extension/DefaultFormTypeExtension.php

class DefaultFormTypeExtension extends AbstractTypeExtension
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        if (null !== $options['default']) {
            $builder->addEventListener(
                FormEvents::PRE_SET_DATA,
                function (FormEvent $event) use ($options) {
                    if (null === $event->getData()) {
                        $event->setData($options['default']);
                    }
                }
            );
        }
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefault('default', null);
    }

    public function getExtendedType()
    {
        return FormType::class;
    }
}

フォーム拡張を登録します。

app.form_type_extension:
    class: App\Form\Extension\DefaultFormTypeExtension
    tags:
        - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }

その後、任意のフォームフィールドでdefaultオプションを使用できます。

$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
9
yceruto

使用しないでください:

'data' => 'Default value'

ここを読む: https://symfony.com/doc/current/reference/forms/types/form.html#data

」データオプションは、レンダリング時に常にドメインデータ(オブジェクト)から取得した値をオーバーライドします。これは、フォームがすでに永続化されたオブジェクトを編集するときにオブジェクト値もオーバーライドされることを意味します。フォームの送信時に保持される値。 "


以下を使用します。

たとえば、この例では、Entity Fooがあり、フィールド「active」があります(この例ではCheckBoxTypeですが、プロセスは他のすべてのタイプと同じです)。

FooFormTypeクラスに以下を追加します。

...
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
...
public function buildForm( FormBuilderInterface $builder, array $options )
{
    ...

    $builder->add('active', CheckboxType::class, array(
        'label' => 'Active',
    ));

    $builder->addEventListener(
        FormEvents::PRE_SET_DATA,
        function(FormEvent $event){                 
            $foo = $event->getData();
            // Set Active to true (checked) if form is "create new" ($foo->active = null)
            if(is_null($foo->getActive())) $foo->setActive(true);
        }
   );
}
public function configureOptions( OptionsResolver $resolver )
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle:Foo',
    ));
}
6
cure85
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
     $form = $event->getForm(); 
     $data = $event->getData(); 

     if ($data == null) {
         $form->add('position', IntegerType::class, array('data' => 0));
     }

});
6
ziiweb

Symfony 2.7でFormBuilderを使用してフォームを生成している場合、初期データをControlerのcreateFormBuilderメソッドに渡すこともできます

$values = array(
    'name' => "Bob"
);

$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');
4
Bob

私の解決策:

$defaultvalue = $options['data']->getMyField();
$builder->add('myField', 'number', array(
            'data' => !empty($defaultvalue) ? $options['data']->getMyField() : 0
        )) ;
4
trocolo

ちょうどそう私は問題を理解しています。

エンティティのデータに基づいてフォームの構築方法を調整する必要があります。エンティティが作成されている場合、デフォルト値を使用します。エンティティが存在する場合は、データベース値を使用します。

個人的には、@ MolecularMansのソリューションが道だと思います。実際には、コンストラクターまたはプロパティステートメントでデフォルト値を設定します。しかし、あなたはそのアプローチが好きではないようです。

代わりに、これに従うことができます: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

フォームタイプにリスナーを掛けると、エンティティを調べて、新しいエンティティまたは既存のエンティティに基づいて、builder-> addステートメントを適宜調整できます。デフォルト値をどこかで指定する必要がありますが、リスナーにコーディングするだけでもかまいません。または、それらをフォームタイプに渡します。

しかし、多くの仕事のようです。エンティティをデフォルト値がすでに設定されているフォームに渡すだけの方が良いでしょう。

4
Cerad

多くの場合、フォームiの初期値にはフィクスチャを使用します。原因のこの方法は簡単ではありませんが、非常に快適です。

例:

class LoadSurgeonPlanData implements FixtureInterface
{
    public function load(ObjectManager $manager)
    {
        $surgeonPlan = new SurgeonPlan();

        $surgeonPlan->setName('Free trial');
        $surgeonPlan->setPrice(0);
        $surgeonPlan->setDelayWorkHours(0);
        $surgeonPlan->setSlug('free');

        $manager->persist($surgeonPlan);
        $manager->flush();        
    }   
}

それでも、symfonyのtypeフィールドにはオプション data があります。

$builder->add('token', 'hidden', array(
    'data' => 'abcdef',
));
3

非常に簡単な方法があり、ここでデフォルトを設定できます:

$defaults = array('sortby' => $sortby,'category' => $category,'page' => 1);

$form = $this->formfactory->createBuilder('form', $defaults)
->add('sortby','choice')
->add('category','choice')
->add('page','hidden')
->getForm();
3
Alsatian

作成フォームで「データ」を設定すると、エンティティの編集時にこの値は変更されません。

私の解決策は次のとおりです。

public function buildForm(FormBuilderInterface $builder, array $options) {
    // In my example, data is an associated array
    $data = $builder->getData();

    $builder->add('myfield', 'text', array(
     'label' => 'Field',
     'data' => array_key_exits('myfield', $data) ? $data['myfield'] : 'Default value',
    ));
}

またね.

2
Quentin Machard

デフォルト値は、対応するエンティティを構成することにより設定されます。エンティティをフォームにバインドする前に、その色フィールドを「#0000FF」に設定します。

// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);
1
Molecular Man

通常、エンティティの特定のフィールドにデフォルト値を設定するだけです。

/**
 * @var int
 * @ORM\Column(type="integer", nullable=true)
 */
protected $development_time = 0;

これは、新しいレコードまたは既存のレコードを更新する場合にのみ機能します。

1
matotej

そのフィールドがエンティティにバインドされている場合(そのエンティティのプロパティである場合)、デフォルト値を設定できます。

例:

public function getMyField() {
    if (is_null($this->MyField)) {
        $this->setMyField('my default value');
    }
    return $this->MyField;
}
1

ブライアンが尋ねたように:

empty_dataは、値なしで送信された場合にのみフィールドを1に設定するように見えます。値が存在しない場合に、フォームがデフォルトで入力に1を表示するようにしたい場合はどうでしょうか。

empty_valueでデフォルト値を設定できます

$builder->add('myField', 'number', ['empty_value' => 'Default value'])
1
Snowirbis

attrvalueを追加して、この問題を解決しました。

->add('projectDeliveringInDays', null, [
    'attr' => [
          'min'=>'1',
          'value'=>'1'
          ]
     ])
0
Kaxa

Symfony 3.4でこの問題を解決します

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('field');

    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $e) {
        if (!$e->getData()) {
            // in create new mode
            $e->getForm()
                ->add('field', NumberType::class, ['data' => 0 /*Default value here*/] );
        }
    });
}
0
user9133301