มีวิธีง่าย ๆ ในการตั้งค่าเริ่มต้นสำหรับเขตข้อมูลฟอร์มข้อความหรือไม่
มีวิธีง่าย ๆ ในการตั้งค่าเริ่มต้นสำหรับเขตข้อมูลฟอร์มข้อความหรือไม่
คำตอบ:
สามารถใช้ระหว่างการสร้างได้อย่างง่ายดายด้วย:
->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 ('ค่าเริ่มต้น'); แต่สิ่งนี้เรียกว่าทุกครั้งที่คุณโหลดเอนทิตี (db หรือไม่) และจะยุ่งเล็กน้อย อย่างไรก็ตามมันจะใช้ได้กับทุกประเภทเขตข้อมูลเพราะคุณสามารถสร้างวันที่หรืออะไรก็ได้ที่คุณต้องการ
หากงบภายในได้ของ ฉันจะไม่ แต่คุณสามารถ
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
โรงงาน / อินสแตนซ์ เรียกใช้ฟังก์ชันแบบสแตติก / คลาสรองซึ่งให้เอนทิตีที่เป็นค่าเริ่มต้นซึ่งมีข้อมูลล่วงหน้าให้คุณ เช่น
function getFactory() {
$obj = new static();
$obj->setBar('foo');
$obj->setFoo('bar');
return $obj;
}
ไม่เหมาะอย่างยิ่งสำหรับคุณจะต้องรักษาฟังก์ชั่นนี้ถ้าคุณเพิ่มเขตข้อมูลพิเศษ แต่มันหมายความว่าคุณกำลังแยกตัวตั้งค่าข้อมูล / ค่าเริ่มต้นและสิ่งที่สร้างขึ้นจาก db ในทำนองเดียวกันคุณสามารถมีหลาย getFactories หากคุณต้องการข้อมูลเริ่มต้นที่แตกต่างกัน
เอนทิตีExtended / Reflectionสร้างเอนทิตีที่ขยาย (เช่น FooCreate ขยาย Foo) ซึ่งให้ข้อมูลเริ่มต้นในเวลาสร้าง (ผ่านตัวสร้าง) คล้ายกับแนวคิดโรงงาน / อินสแตนซ์เพียงแนวทางที่แตกต่าง - ฉันชอบวิธีการคงที่เป็นการส่วนตัว
ตั้งค่าข้อมูลก่อนที่จะสร้างแบบฟอร์ม ในตัวสร้าง / บริการคุณรู้ว่าคุณมีเอนทิตีใหม่หรือว่ามันถูกเติมจากฐานข้อมูล ดังนั้นจึงเป็นไปได้ที่จะเรียกใช้ชุดข้อมูลในฟิลด์ต่างๆเมื่อคุณคว้าเอนทิตีใหม่ เช่น
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
กิจกรรมของฟอร์ม เมื่อคุณสร้างฟอร์มที่คุณตั้งค่าข้อมูลเริ่มต้นเมื่อสร้างฟิลด์ คุณแทนที่การใช้งาน PreSetData ฟังเหตุการณ์นี้ ปัญหานี้คือคุณกำลังทำซ้ำเวิร์กโหลด / โค้ดที่ซ้ำกันและทำให้ยากที่จะรักษา / เข้าใจ
แบบฟอร์มเพิ่มเติม คล้ายกับเหตุการณ์แบบฟอร์ม แต่คุณเรียกใช้ชนิดอื่นขึ้นอยู่กับว่าเป็นเอนทิตี db / ใหม่หรือไม่ ด้วยวิธีนี้ฉันหมายความว่าคุณมี FooType ซึ่งกำหนดรูปแบบการแก้ไขของคุณ BarType จะขยาย FooType สิ่งนี้และตั้งค่าข้อมูลทั้งหมดให้กับเขตข้อมูล ในตัวควบคุมของคุณคุณเพียงแค่เลือกชนิดฟอร์มที่จะสร้าง สิ่งนี้แย่มากถ้าคุณมีธีมที่กำหนดเองและชอบกิจกรรมสร้างการบำรุงรักษามากเกินไปสำหรับความชอบของฉัน
Twig คุณสามารถสร้างชุดรูปแบบของคุณเองและใช้ข้อมูลเป็นค่าเริ่มต้นโดยใช้ตัวเลือกค่าเช่นกันเมื่อคุณทำตามแต่ละฟิลด์ ไม่มีอะไรหยุดคุณห่อนี้เป็นชุดรูปแบบทั้งในกรณีที่คุณต้องการให้แม่แบบของคุณสะอาดและนำมาใช้ใหม่แบบฟอร์ม เช่น
form_widget(form.foo, {attr: { value : default } });
JS มันจะไม่สำคัญที่จะเติมแบบฟอร์มด้วยฟังก์ชั่น JS ถ้าเขตข้อมูลว่างเปล่า คุณสามารถทำบางอย่างกับตัวยึดตำแหน่งได้ นี่เป็นความคิดที่เลวร้าย
แบบฟอร์มเป็นบริการ สำหรับหนึ่งในโครงการขนาดใหญ่ที่ฉันทำฉันได้สร้างบริการที่สร้างทุกรูปแบบทำการประมวลผลทั้งหมดและอื่น ๆ เพราะนี่คือรูปแบบที่จะใช้ในหลาย ๆ ตัวควบคุมในสภาพแวดล้อมที่หลากหลายและในขณะที่รูปแบบ ถูกสร้างขึ้น / จัดการในลักษณะเดียวกันพวกเขาจะแสดง / โต้ตอบกับแตกต่างกัน (เช่นการจัดการข้อผิดพลาดการเปลี่ยนเส้นทาง ฯลฯ ) ความสวยงามของวิธีการนี้คือคุณสามารถเริ่มต้นข้อมูลทำทุกสิ่งที่คุณต้องการจัดการข้อผิดพลาดโดยทั่วไป ฯลฯ และมันถูกห่อหุ้มทั้งหมดในที่เดียว
สรุป เมื่อฉันเห็นคุณจะพบปัญหาครั้งแล้วครั้งเล่า - ข้อมูลเริ่มต้นอยู่ที่ไหน
ด้วยเหตุนี้ฉันได้เข้าหาปัญหาที่แตกต่างกันในแต่ละครั้ง ตัวอย่างเช่นตัวเลือก "จดหมายข่าว" แบบฟอร์มการสมัครได้อย่างง่ายดาย (และมีเหตุผล) ตั้งในนวกรรมิกก่อนที่จะสร้างแบบฟอร์ม เมื่อฉันสร้างคอลเลกชันแบบฟอร์มที่เชื่อมโยงกัน (เช่นปุ่มตัวเลือกในประเภทรูปแบบที่ต่างกันเชื่อมโยงกัน) จากนั้นฉันได้ใช้ Event Listeners เมื่อฉันสร้างเอนทิตี้ที่ซับซ้อนมากขึ้น (เช่นที่ต้องการลูกหรือข้อมูลที่ผิดนัด) ฉันใช้ฟังก์ชั่น (เช่น 'getFactory') เพื่อสร้างองค์ประกอบตามที่ฉันต้องการ
ฉันไม่คิดว่าจะมีวิธีการ "ถูกต้อง" ที่ทุกครั้งที่ฉันมีข้อกำหนดนี้มันแตกต่างกันเล็กน้อย
โชคดี! ฉันหวังว่าฉันจะให้อาหารคุณคิดในราคาใด ๆ และไม่ได้เดินเล่นมากเกินไป)
ถ้าคุณต้องการตั้งค่าเริ่มต้นและแบบฟอร์มของคุณเกี่ยวข้องกับเอนทิตีคุณควรใช้วิธีการดังต่อไปนี้:
// 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 จากความคิดเห็นในลิงค์ด้านบนและคำตอบของ Dmitriy (ไม่ใช่ที่ยอมรับ) จากวิธีการตั้งค่าเริ่มต้นสำหรับเขตข้อมูลฟอร์มใน Symfony2
เพิ่มค่าเริ่มต้นให้กับแอตทริบิวต์ data เมื่อเพิ่มเขตข้อมูลด้วย FormBuilder ซึ่งดัดแปลงมาจากคำตอบของ Dmitriy
โปรดทราบว่านี่ถือว่าคุณสมบัติจะและจะมีค่าเป็นโมฆะเมื่อมันเป็นสิ่งใหม่และไม่ใช่เอนทิตีที่มีอยู่
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
"ตัวเลือกข้อมูลจะแทนที่ค่าที่นำมาจากข้อมูลโดเมน (วัตถุ) เมื่อแสดงผลซึ่งหมายความว่าค่าวัตถุจะถูกแทนที่เมื่อแบบฟอร์มแก้ไขวัตถุที่คงอยู่แล้วทำให้สูญเสียมูลค่าที่คงอยู่เมื่อส่งแบบฟอร์ม"
ใช้สิ่งต่อไปนี้:
ให้บอกว่าสำหรับตัวอย่างนี้คุณมี Entity 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()
แทนที่จะอ่านข้อมูลอาจทำให้ดียิ่งขึ้น
ทางออกของฉัน:
$defaultvalue = $options['data']->getMyField();
$builder->add('myField', 'number', array(
'data' => !empty($defaultvalue) ? $options['data']->getMyField() : 0
)) ;
เพียงแค่ฉันเข้าใจปัญหา
คุณต้องการปรับวิธีการสร้างฟอร์มตามข้อมูลในเอนทิตีของคุณ หากมีการสร้างเอนทิตีใช้ค่าเริ่มต้นบางอย่าง ถ้ามีเอนทิตีอยู่แล้วให้ใช้ค่าฐานข้อมูล
ส่วนตัวฉันคิดว่าวิธีแก้ปัญหาของ @ MolecularMans เป็นวิธีที่จะไป ฉันจะตั้งค่าเริ่มต้นจริงในตัวสร้างหรือในคำสั่งคุณสมบัติ แต่ดูเหมือนคุณจะไม่ชอบวิธีการนี้
แต่คุณสามารถติดตามสิ่งนี้ได้ที่: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
คุณวางผู้ฟังกับชนิดฟอร์มของคุณและจากนั้นคุณสามารถตรวจสอบเอนทิตีของคุณและปรับตัวสร้าง -> เพิ่มคำสั่งตามตามที่มีเอนทิตีใหม่หรือที่มีอยู่แล้ว คุณยังคงต้องระบุค่าเริ่มต้นของคุณอยู่ที่ไหนสักแห่งแม้ว่าคุณจะสามารถเขียนโค้ดลงในผู้ฟังได้ หรือส่งต่อไปยังประเภทฟอร์ม
ดูเหมือนว่าจะทำงานมากมาย ดีกว่าที่จะส่งเอนทิตีไปยังแบบฟอร์มด้วยค่าเริ่มต้นที่ตั้งไว้แล้ว
หากคุณใช้FormBuilder
ใน symfony 2.7 เพื่อสร้างแบบฟอร์มคุณสามารถส่งข้อมูลเริ่มต้นไปยังcreateFormBuilder
วิธีการของ Controler
$values = array(
'name' => "Bob"
);
$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');
บ่อยครั้งสำหรับค่าเริ่มต้นเริ่มต้นของแบบฟอร์มฉันใช้ส่วนควบ ด้วยเหตุนี้วิธีนี้จึงไม่ง่าย แต่สะดวกสบายมาก
ตัวอย่าง:
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 มีตัวเลือกข้อมูล
ตัวอย่าง
$builder->add('token', 'hidden', array(
'data' => 'abcdef',
));
มีวิธีที่ง่ายมากคุณสามารถตั้งค่าเริ่มต้นได้ที่นี่:
$defaults = array('sortby' => $sortby,'category' => $category,'page' => 1);
$form = $this->formfactory->createBuilder('form', $defaults)
->add('sortby','choice')
->add('category','choice')
->add('page','hidden')
->getForm();
หากคุณตั้งค่า 'ข้อมูล' ในแบบฟอร์มการสร้างของคุณค่านี้จะไม่ถูกแก้ไขเมื่อแก้ไขเอนทิตีของคุณ
ทางออกของฉันคือ
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;
}
โดยปกติฉันเพิ่งตั้งค่าเริ่มต้นสำหรับฟิลด์เฉพาะในเอนทิตีของฉัน:
/**
* @var int
* @ORM\Column(type="integer", nullable=true)
*/
protected $development_time = 0;
วิธีนี้จะใช้งานได้กับระเบียนใหม่หรือหากเพิ่งอัปเดตรายการที่มีอยู่
'empty_data'
มีการเรียกกลับถูกใช้เพื่ออนุญาตให้พารามิเตอร์คอนสตรัคเตอร์ในเอนทิตี
ดังที่ไบรอันถามว่า:
empty_data ปรากฏขึ้นเพื่อตั้งค่าฟิลด์เป็น 1 เท่านั้นเมื่อถูกส่งโดยไม่มีค่า สิ่งที่เกี่ยวกับเมื่อคุณต้องการรูปแบบเริ่มต้นที่จะแสดง 1 ในการป้อนข้อมูลเมื่อไม่มีค่าอยู่?
คุณสามารถตั้งค่าเริ่มต้นด้วย empty_value
$builder->add('myField', 'number', ['empty_value' => 'Default value'])
ฉันแก้ไขปัญหานี้โดยการเพิ่มมูลค่าในattr :
->add('projectDeliveringInDays', null, [
'attr' => [
'min'=>'1',
'value'=>'1'
]
])