テキストフォームフィールドのデフォルト値を設定する簡単な方法はありますか?
テキストフォームフィールドのデフォルト値を設定する簡単な方法はありますか?
回答:
作成中に簡単に使用できます:
->add('myfield', 'text', array(
'label' => 'Field',
'empty_data' => 'Default value'
))
'data'
キーを'value'
empty_data
data
役に立たない-保存された値を上書きします。empty_data
値は表示されません。空の値の送信時に使用され、チェックされていない選択肢を保存することができなくなります。
デフォルト値を設定できます empty_data
$builder->add('myField', 'number', ['empty_data' => 'Default value'])
私はこれを過去に何度か考えたことがあります。そのため、これまでに使用したさまざまなアイデアを書き留めておきます。何かが役に立つかもしれませんが、「完璧な」Symfony2ソリューションはありません。
コンストラクター エンティティでは、$ 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 extends Fooなど)を作成します。これにより、作成時に(コンストラクタを介して)デフォルトのデータが提供されます。ファクトリー/インスタンスのアイデアと同様に、異なるアプローチ-私は静的メソッドを個人的に好みます。
ビルドフォームの前にデータを設定 コンストラクター/サービスで、新しいエンティティがあるかどうか、またはそれがdbから入力されたかどうかがわかります。したがって、新しいエンティティを取得するときに、さまざまなフィールドのセットデータを呼び出すのがもっともです。例えば
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
フォームイベント を作成するとき、フィールドを作成するときにデフォルトのデータを設定します。これをオーバーライドするには、PreSetDataイベントリスナーを使用します。これの問題は、フォームのワークロードを複製したり、コードを複製したりして、維持/理解を困難にすることです。
拡張 フォームFormイベントに似ていますが、db /新しいエンティティであるかどうかに応じて異なるタイプを呼び出します。これは、編集フォームを定義するFooTypeがあることを意味します。BarTypeはこれをFooTypeに拡張し、すべてのデータをフィールドに設定します。次にコントローラーで、起動するフォームタイプを選択するだけです。ただし、カスタムテーマがあり、イベントが好きな場合、これは私の好みではメンテナンスが多すぎます。
小枝 フィールドごとに行う場合、独自のテーマを作成し、値オプションを使用してデータをデフォルト設定することもできます。テンプレートをクリーンに保ち、フォームを再利用できるようにしたい場合でも、これをフォームテーマにラップすることを妨げるものはありません。例えば
form_widget(form.foo, {attr: { value : default } });
JS フィールドが空の場合、フォームにJS関数を入力するのは簡単です。たとえば、プレースホルダーを使用して何かを行うことができます。しかし、これは悪い、悪い考えです。
サービスとしてのフォーム 私が行った大きなフォームベースのプロジェクトの1つすべてのフォームを生成し、すべての処理などを行うサービスを作成しました。これは、フォームが複数の環境の複数のコントローラー間で使用され、同じ方法で生成/処理され、表示/操作方法が異なります(エラー処理、リダイレクトなど)。このアプローチの優れた点は、データのデフォルト設定、必要なすべての処理、一般的なエラーの処理などを行うことができ、すべてが1か所にカプセル化されていることです。
結論 ご覧のとおり、同じ問題が何度も発生します。デフォルトのデータはどこに保存されますか?
そのために、私は毎回異なる方法で問題に取り組みました。たとえば、サインアップフォームの「ニュースレター」オプションは、フォームを作成する直前にコンストラクターで簡単に(かつ論理的に)設定できます。一緒にリンクされたフォームコレクション(たとえば、さまざまなフォームタイプのどのラジオボタンが一緒にリンクされているか)を作成していたとき、イベントリスナーを使用しました。より複雑なエンティティ(たとえば、子または多くのデフォルトデータが必要なエンティティ)を構築したとき、必要に応じて関数(たとえば、「getFactory」)を使用して要素を作成しました。
私はこの要件があるたびに少し異なるため、「正しい」アプローチは1つとは思いません。
幸運を!とにかく私があなたに考えさせるための食べ物を与えて、あまり騒ぎすぎなかったことを願っています;)
デフォルト値を設定する必要があり、フォームがエンティティに関連している場合は、次のアプローチを使用する必要があります。
// 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
エンティティから値を取得するのではなく、常にデフォルト値に設定されます。
$options['data']->getMyField()
と$option['data']['myField']
empty_data
:このオプションは、送信された値が空の場合にフィールドが返す値を決定します。初期値は設定しません
モデルクラスの関連フィールドのデフォルトを設定できます(マッピング定義で、または自分で値を設定)。
さらに、FormBuilderは、setData()メソッドで初期値を設定する機会を提供します。フォームビルダーは、フォームクラスのcreateForm()メソッドに渡されます。
また、このリンクを確認してください:http : //symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
フォームがエンティティにバインドされている場合は、構成メソッドを使用してエンティティ自体にデフォルト値を設定するだけです。
public function __construct()
{
$this->field = 'default value';
}
'mapped' => false
)。setData(...)
これらに使用します。
アプローチ1(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でフィールドを追加するときに、データ属性にデフォルト値を追加します。
これは、プロパティが新しいエンティティであり、既存のエンティティではない場合にのみ nullの値を持つことを想定していることに注意してください。
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'
)
);
}
たとえば、フォームのデフォルト値を次のように設定できます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'));
使用しないでください:
'data' => 'Default value'
こちらをお読みください:https : //symfony.com/doc/current/reference/forms/types/form.html#data
「データオプションは、レンダリング時に常にドメインデータ(オブジェクト)から取得した値をオーバーライドします。これは、フォームが既に永続化されているオブジェクトをフォームが編集すると、オブジェクト値もオーバーライドされ、フォームが送信されたときに永続化された値が失われることを意味します。」
以下を使用します。
この例の場合、エンティティFooがあり、「アクティブ」フィールド(この例では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',
));
}
'data' => $data['myfield'] ?? 'Default value'
->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));
}
});
$event->setData()
の代わりに、フィールドをreaddingは、それがさらに良くなるかもしれません。
ちょうど私は問題を理解しています。
エンティティのデータに基づいてフォームが構築される方法を調整したいとします。エンティティが作成されている場合は、デフォルト値を使用します。エンティティが存在する場合は、データベース値を使用します。
個人的には、@ MolecularMansの解決策が進むべき道だと思います。実際には、コンストラクターまたはプロパティステートメントでデフォルト値を設定します。しかし、あなたはそのアプローチが好きではないようです。
代わりに、これに従うことができます:http : //symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
リスナーをフォームタイプにぶら下げて、エンティティを調べ、新しいエンティティまたは既存のエンティティに基づいて、それに応じてbuilder-> addステートメントを調整できます。デフォルト値をリスナーでコーディングすることもできますが、どこかにデフォルト値を指定する必要があります。または、フォームタイプに渡します。
しかし、多くの作業のようです。デフォルト値がすでに設定されているエンティティをフォームに渡すだけの方が良いでしょう。
多くの場合、フォームの初期値には、フィクスチャを使用します。当然のことながら、この方法は簡単ではありませんが、非常に快適です。
例:
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',
));
作成フォームで「データ」を設定した場合、エンティティを編集してもこの値は変更されません。
私の解決策は:
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',
));
}
さようなら。
'data' => $data['myfield'] ?? 'Default value',
デフォルト値は、対応するエンティティを構成することによって設定されます。エンティティをフォームにバインドする前に、その色フィールドを「#0000FF」に設定します。
// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);
そのフィールドがエンティティにバインドされている(そのエンティティのプロパティである)場合、デフォルト値を設定するだけで済みます。
例:
public function getMyField() {
if (is_null($this->MyField)) {
$this->setMyField('my default value');
}
return $this->MyField;
}