วิธีการตั้งค่าเริ่มต้นสำหรับเขตข้อมูลฟอร์มใน Symfony2


137

มีวิธีง่าย ๆ ในการตั้งค่าเริ่มต้นสำหรับเขตข้อมูลฟอร์มข้อความหรือไม่


1
ใช่ แต่คำตอบที่ให้ไว้ในคำถามนี้ไม่เป็นที่พอใจ / ไม่ทำงาน ... ฉันจะเพิ่ม "แก้ไข" เพื่ออธิบายว่าทำไม :-)
herrjeh42

ดูเหมือนว่าโซลูชัน 'สมบูรณ์แบบ' ที่คุณเป็นหลังจากนั้นคือฟิลด์ที่มีตัวเลือก 'default_value' สิ่งที่เป็นปัจจุบันมันไม่ดังนั้นฉันไม่คิดว่าโซลูชั่นที่สมบูรณ์แบบที่คุณกำลังมองหาอยู่ในปัจจุบัน สิ่งเดียวที่ symfony นำเสนอ (ดูลิงก์) คือตัวเลือกข้อมูล ดังนั้นถ้าเป็นวิธีการเดียวที่ฉันสามารถดูเอทีเอ็ม แม้ว่าจะมีตัวเลือก 'default_value' อยู่ในฟิลด์ แต่ฉันคิดว่ามันจะทำสิ่งเดียวกันภายใน
crysallus

นอกจากนี้ฉันได้แก้ไขคำตอบของฉันในวิธีที่ 2 ตามความคิดเห็นของฉันด้านล่าง หากวิธีนี้แก้ไขปัญหาไวยากรณ์ที่คุณกล่าวถึงในจุดที่ 2 คุณอาจต้องการแก้ไขความคิดเห็นนั้น หรือแจ้งให้เราทราบว่าปัญหาคืออะไรและฉันจะแก้ไขคำตอบของฉัน
crysallus

1
@Crone คำถามนี้ถูกถามเมื่อ 2 ปีก่อน
Ondrej Slinták

1
@ OndrejSlintákฉันไม่ได้ลงคะแนนให้ปิดเป็น dupe แต่ FYI: ไม่สำคัญว่าจะมาก่อนใคร" หากคำถามใหม่เป็นคำถามที่ดีกว่าหรือมีคำตอบที่ดีกว่าให้ลงคะแนนเพื่อปิดคำถามเก่า ของใหม่ "
Jeff Puckett

คำตอบ:


105

สามารถใช้ระหว่างการสร้างได้อย่างง่ายดายด้วย:

->add('myfield', 'text', array(
     'label' => 'Field',
     'empty_data' => 'Default value'
))

11
สำหรับ Symfony 2.1 ฉันต้องการที่จะเปลี่ยน'data'ที่สำคัญในการ'value'
Edd

175
สิ่งนี้ไม่เพียงตั้งค่าเริ่มต้นเท่านั้น แต่จะบังคับค่าภายใต้บริบทใด ๆ ไม่ใช่สิ่งที่ฉันจะเรียกว่า "ค่าเริ่มต้น" ...
Hubert Perron

4
ฉันลงคะแนนโซลูชันนี้ไม่ใช่วิธีแก้ปัญหา (ตามที่ฮิวเบิร์ตเพโรรอนกล่าวถึงข้างต้น) ฉันกำลังพยายามหาทางออกที่ดีกว่าในโพสต์นี้stackoverflow.com/questions/17986481//
herrjeh42

13
นี่เป็นค่าเริ่มต้นค่าเริ่มต้นคือempty_data
Pierre de LESPINAY

3
dataไม่มีประโยชน์ - มันเขียนทับค่าที่บันทึกไว้ empty_dataไม่แสดงค่ามันใช้กับการส่งค่าที่ว่างเปล่าและทำให้ไม่สามารถบันทึกตัวเลือกที่ไม่ได้ตรวจสอบได้
moldcraft

115

คุณสามารถตั้งค่าเริ่มต้นด้วย empty_data

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

29
การตั้งค่าข้อมูลไม่ได้เป็นการตั้งค่าเริ่มต้น คำตอบนี้ถูกต้อง
Alexei Tenitski

9
ดูเหมือนว่าจะตั้งค่าฟิลด์เป็น 1 เท่านั้นเมื่อมีการส่งโดยไม่มีค่า สิ่งที่เกี่ยวกับเมื่อคุณต้องการรูปแบบเริ่มต้นที่จะแสดง 1 ในการป้อนข้อมูลเมื่อไม่มีค่าอยู่?
Brian

ในการทดสอบ empty_data ของฉันไม่อนุญาตให้ฉันแทนที่ค่าเริ่มต้นจากเขตข้อมูลที่ส่งว่างเปล่าเช่นถ้าคุณต้องการบันทึกลงในฐานข้อมูลเป็น 0 แทนที่จะเป็น NULL ข้อผิดพลาดนี้ยังคงโดดเด่นเท่าที่ฉันสามารถบอกได้: github.com/symfony/symfony/issues/5906
Chadwick Meyer

63

ฉันเคยไตร่ตรองเรื่องนี้มาแล้วสองสามครั้งในอดีตดังนั้นคิดว่าฉันจดความคิดต่าง ๆ ที่ฉันเคยใช้ บางสิ่งอาจใช้งานได้ แต่ไม่มีโซลูชัน 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 ถ้าเขตข้อมูลว่างเปล่า คุณสามารถทำบางอย่างกับตัวยึดตำแหน่งได้ นี่เป็นความคิดที่เลวร้าย

แบบฟอร์มเป็นบริการ สำหรับหนึ่งในโครงการขนาดใหญ่ที่ฉันทำฉันได้สร้างบริการที่สร้างทุกรูปแบบทำการประมวลผลทั้งหมดและอื่น ๆ เพราะนี่คือรูปแบบที่จะใช้ในหลาย ๆ ตัวควบคุมในสภาพแวดล้อมที่หลากหลายและในขณะที่รูปแบบ ถูกสร้างขึ้น / จัดการในลักษณะเดียวกันพวกเขาจะแสดง / โต้ตอบกับแตกต่างกัน (เช่นการจัดการข้อผิดพลาดการเปลี่ยนเส้นทาง ฯลฯ ) ความสวยงามของวิธีการนี้คือคุณสามารถเริ่มต้นข้อมูลทำทุกสิ่งที่คุณต้องการจัดการข้อผิดพลาดโดยทั่วไป ฯลฯ และมันถูกห่อหุ้มทั้งหมดในที่เดียว

สรุป เมื่อฉันเห็นคุณจะพบปัญหาครั้งแล้วครั้งเล่า - ข้อมูลเริ่มต้นอยู่ที่ไหน

  • หากคุณเก็บไว้ที่ระดับ db / doctrine จะเกิดอะไรขึ้นหากคุณไม่ต้องการจัดเก็บค่าเริ่มต้นทุกครั้ง
  • หากคุณเก็บไว้ที่ระดับเอนทิตีจะเกิดอะไรขึ้นถ้าคุณต้องการใช้เอนทิตีนั้นที่อื่นโดยไม่มีข้อมูลอยู่ในนั้น
  • หากคุณเก็บไว้ที่ระดับเอ็นติตี้และเพิ่มฟิลด์ใหม่คุณต้องการให้เวอร์ชันก่อนหน้ามีค่าเริ่มต้นนั้นเมื่อทำการแก้ไขหรือไม่? กันไปสำหรับการเริ่มต้นใน DB ...
  • หากคุณเก็บไว้ที่ระดับฟอร์มจะเห็นได้ชัดว่าเมื่อคุณมาเพื่อรักษารหัสในภายหลัง
  • หากอยู่ในตัวสร้างจะเกิดอะไรขึ้นถ้าคุณใช้แบบฟอร์มในหลาย ๆ ที่?
  • หากคุณผลักมันไปที่ระดับ JS แล้วคุณไปไกลเกินไป - ข้อมูลไม่ควรอยู่ในมุมมองของ JS (และเราเพิกเฉยความเข้ากันได้การแสดงผลข้อผิดพลาด ฯลฯ )
  • บริการดีมากถ้าเหมือนฉันคุณใช้มันในหลาย ๆ ที่ แต่มันเกินราคาสำหรับการเพิ่ม / แก้ไขแบบฟอร์มบนเว็บไซต์เดียว ...

ด้วยเหตุนี้ฉันได้เข้าหาปัญหาที่แตกต่างกันในแต่ละครั้ง ตัวอย่างเช่นตัวเลือก "จดหมายข่าว" แบบฟอร์มการสมัครได้อย่างง่ายดาย (และมีเหตุผล) ตั้งในนวกรรมิกก่อนที่จะสร้างแบบฟอร์ม เมื่อฉันสร้างคอลเลกชันแบบฟอร์มที่เชื่อมโยงกัน (เช่นปุ่มตัวเลือกในประเภทรูปแบบที่ต่างกันเชื่อมโยงกัน) จากนั้นฉันได้ใช้ Event Listeners เมื่อฉันสร้างเอนทิตี้ที่ซับซ้อนมากขึ้น (เช่นที่ต้องการลูกหรือข้อมูลที่ผิดนัด) ฉันใช้ฟังก์ชั่น (เช่น 'getFactory') เพื่อสร้างองค์ประกอบตามที่ฉันต้องการ

ฉันไม่คิดว่าจะมีวิธีการ "ถูกต้อง" ที่ทุกครั้งที่ฉันมีข้อกำหนดนี้มันแตกต่างกันเล็กน้อย

โชคดี! ฉันหวังว่าฉันจะให้อาหารคุณคิดในราคาใด ๆ และไม่ได้เดินเล่นมากเกินไป)


คุณสามารถให้รายละเอียดเพิ่มเติมเล็กน้อยเกี่ยวกับสิ่งที่คุณหมายถึง 'บริการที่สร้างแบบฟอร์มทั้งหมด' ได้หรือไม่ฉันกำลังทำงานในโครงการที่มีรูปแบบเป็นศูนย์กลางจริงๆในตอนนี้และมันจะดีมากถ้ามีมุมมองที่แตกต่างกัน
user2268997

2
เมื่อใช้หลักคำสอนจะไม่เรียกตัวสร้างเมื่อเอนทิตีถูกโหลดจาก db
NDM

43

ถ้าคุณต้องการตั้งค่าเริ่มต้นและแบบฟอร์มของคุณเกี่ยวข้องกับเอนทิตีคุณควรใช้วิธีการดังต่อไปนี้:

// 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']
ggg

3
นี่เป็นวิธีที่เหมาะสมสำหรับทั้งการเพิ่ม / อัปเดตฉันคิดว่า แต่ฉันเกลียด Symfony ทำให้ซับซ้อนเกินไป
Yarco

นี่เป็นคำตอบเดียวที่ดี ฉันไม่เข้าใจคำตอบอื่น ๆ เมื่อฉันดูเอกสาร empty_data: ตัวเลือกนี้จะกำหนดว่าฟิลด์จะส่งคืนค่าใดเมื่อค่าที่ส่งว่างเปล่า ไม่ได้ตั้งค่าเริ่มต้น
Vincent Decaux

19

คุณสามารถตั้งค่าเริ่มต้นสำหรับฟิลด์ที่เกี่ยวข้องในคลาสโมเดลของคุณ (ในการกำหนดแผนที่หรือตั้งค่าด้วยตัวคุณเอง)

นอกจากนี้ FormBuilder ให้คุณมีโอกาสที่จะตั้งค่าเริ่มต้นด้วยsetData ()วิธีการ เครื่องมือสร้างแบบฟอร์มถูกส่งผ่านไปยังเมธอด createForm ()ของคลาสฟอร์มของคุณ

นอกจากนี้ให้ตรวจสอบลิงก์นี้: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class


16

ถ้าแบบฟอร์มของคุณถูกผูกไว้กับเอนทิตีเพียงแค่ตั้งค่าเริ่มต้นบนเอนทิตีเองโดยใช้วิธีการสร้าง:

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

อย่างไรก็ตามฟอร์มของคุณอาจมีฟิลด์เพิ่มเติมที่ไม่ได้ถูกแมปกับเอนทิตีของคุณ ( 'mapped' => false) ใช้setData(...)สำหรับสิ่งเหล่านี้
Dizzley

12

วิธีที่ 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'
        )
    );
}

อันแรกทำงานได้ (ขอบคุณ!) อันที่สองไม่ได้ (สำหรับฉัน): $ options ["data] ถูกตั้งไว้เสมอดังนั้นค่าเริ่มต้นจะไม่ถูกใช้ฉันยังคงสงสัยว่าทางออกหมายเลข 1 เป็นวิธีที่ตั้งใจหรือไม่ ที่จะทำ ...
herrjeh42

คุณพูดถูกเกี่ยวกับ $ options ['data'] หากคุณไม่ได้กำหนดค่าเริ่มต้นให้กับฟิลด์เอนทิตีคุณสามารถทดสอบค่าว่างบนฟิลด์แทนเช่น 'data' => $ options ['data'] -> getColor ()! == null? ฯลฯ ... ที่ถือว่าค่า Null นั้นไม่ใช่ค่าที่ถูกต้องสำหรับเขตข้อมูลสีดังนั้นเอนทิตีที่มีอยู่จะไม่มีค่า Null สำหรับเขตข้อมูลนั้น
crysallus

อ่าโง่ฉัน: ฉันลองด้วย 'isset ($ $ options [' data '] -> getColor ())' ฉันได้รับข้อความแสดงข้อผิดพลาดเกี่ยวกับ "ไม่อนุญาตให้ใช้มันในการเขียนบริบท" และลืมว่าฉันต้อง ตรวจสอบมันแตกต่างกัน :-)
herrjeh42

1
ที่จริงแล้วดูเหมือนจะมีโอกาสเกิดขึ้นเมื่อไม่ได้ตั้งค่าการป้อนข้อมูล ปลอดภัยกว่าสำหรับการทดสอบทั้ง isset ($ options ['data']) && $ options ['data'] -> getColor ()! == null? ...
crysallus

9

คุณสามารถตั้งค่าเริ่มต้นเช่นแบบฟอร์ม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();

2
ฉันชอบวิธีนี้โดยเฉพาะในแอปพลิเคชันส่วนใหญ่ที่คุณสร้างฟอร์มและส่งผ่านเอนทิตีที่ฟอร์มใช้
skrilled

9

วิธีแก้ปัญหาทั่วไปสำหรับกรณี / แนวทางส่วนใหญ่โดยใช้แบบฟอร์มที่ไม่มีคลาสหรือเมื่อเราต้องการเข้าถึงบริการใด ๆ เพื่อตั้งค่าเริ่มต้น:

// 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'));

ควรได้รับการยอมรับว่าเป็นคำตอบที่ดีที่สุด (ล่าสุด)
medunes

7

อย่าใช้:

'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',
    ));
}

นี่คือเงิน !! ใช้ฟังเหตุการณ์ฟอร์มเพื่อตรวจสอบค่าของคุณก่อนที่จะเริ่มต้นพวกเขา นี่ควรเป็นคำตอบที่ยอมรับได้สำหรับการกำหนดค่าเริ่มต้นในแบบฟอร์มของคุณเพราะใช้ได้ทั้งกับการกระทำใหม่และการแก้ไข
tlorens

นี่เป็นวิธีที่ถูกต้องในการจัดการกับสิ่งนี้และนี่ควรเป็นคำตอบที่ยอมรับได้
Bettinz

สิ่งที่คุณพูดถึงตอนแรกนั้นไม่เป็นความจริงหากคุณใช้เงื่อนไข / ไตรภาค เช่นนี้:'data' => $data['myfield'] ?? 'Default value'
xarlymg89

6
->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()แทนที่จะอ่านข้อมูลอาจทำให้ดียิ่งขึ้น
2268997

5

ทางออกของฉัน:

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

4

เพียงแค่ฉันเข้าใจปัญหา

คุณต้องการปรับวิธีการสร้างฟอร์มตามข้อมูลในเอนทิตีของคุณ หากมีการสร้างเอนทิตีใช้ค่าเริ่มต้นบางอย่าง ถ้ามีเอนทิตีอยู่แล้วให้ใช้ค่าฐานข้อมูล

ส่วนตัวฉันคิดว่าวิธีแก้ปัญหาของ @ MolecularMans เป็นวิธีที่จะไป ฉันจะตั้งค่าเริ่มต้นจริงในตัวสร้างหรือในคำสั่งคุณสมบัติ แต่ดูเหมือนคุณจะไม่ชอบวิธีการนี้

แต่คุณสามารถติดตามสิ่งนี้ได้ที่: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

คุณวางผู้ฟังกับชนิดฟอร์มของคุณและจากนั้นคุณสามารถตรวจสอบเอนทิตีของคุณและปรับตัวสร้าง -> เพิ่มคำสั่งตามตามที่มีเอนทิตีใหม่หรือที่มีอยู่แล้ว คุณยังคงต้องระบุค่าเริ่มต้นของคุณอยู่ที่ไหนสักแห่งแม้ว่าคุณจะสามารถเขียนโค้ดลงในผู้ฟังได้ หรือส่งต่อไปยังประเภทฟอร์ม

ดูเหมือนว่าจะทำงานมากมาย ดีกว่าที่จะส่งเอนทิตีไปยังแบบฟอร์มด้วยค่าเริ่มต้นที่ตั้งไว้แล้ว


4

หากคุณใช้FormBuilderใน symfony 2.7 เพื่อสร้างแบบฟอร์มคุณสามารถส่งข้อมูลเริ่มต้นไปยังcreateFormBuilderวิธีการของ Controler

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

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

3

บ่อยครั้งสำหรับค่าเริ่มต้นเริ่มต้นของแบบฟอร์มฉันใช้ส่วนควบ ด้วยเหตุนี้วิธีนี้จึงไม่ง่าย แต่สะดวกสบายมาก

ตัวอย่าง:

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',
));

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

หากคุณตั้งค่า 'ข้อมูล' ในแบบฟอร์มการสร้างของคุณค่านี้จะไม่ถูกแก้ไขเมื่อแก้ไขเอนทิตีของคุณ

ทางออกของฉันคือ

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',
    ));
}

บาย.


มีประโยชน์มากกว่าคำตอบที่ยอมรับ! ถ้าคุณใช้ PHP7 + คุณสามารถทำให้มันดีขึ้นด้วย:'data' => $data['myfield'] ?? 'Default value',
Boykodev

คุณมีการพิมพ์ผิดในฟังก์ชั่น
Deadpool

1

ค่าเริ่มต้นถูกตั้งค่าโดยการกำหนดค่าเอนทิตีที่สอดคล้องกัน ก่อนที่จะเชื่อมโยงเอนทิตีเพื่อตั้งค่าฟิลด์สีเป็น "# 0000FF":

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

วิธีการนี้ใช้งานได้ แต่มีข้อเสียที่คุณต้องทำทุกครั้งที่คุณใช้คลาสฟอร์มและมันมีรายละเอียดมาก (ชุดคำสั่งจำนวนมาก) เนื่องจากองค์ประกอบของฟอร์มนั้นสวยงามมากจึงต้องมีอย่างอื่น แต่ขอบคุณอยู่ดี :-)
herrjeh42

@ jamie0726 ในความคิดของฉันเป็นความรับผิดชอบของตัวควบคุมในการตั้งค่าของวัตถุเมื่อใดก็ตามที่มันเป็นใหม่หรือดึง ด้วยวิธีนี้คุณสามารถมีรูปแบบที่ใช้ในสถานการณ์ต่าง ๆ ที่มีพฤติกรรมที่แตกต่างกันเช่นสีใหม่อาจเปลี่ยนไปเนื่องจากผู้ใช้มีผู้จัดการหรือบทบาทเหนือมนุษย์และเนื่องจากนี่เป็นตรรกะทางธุรกิจที่ควรควบคุมโดย ควบคุมหรือบริการไม่ใช่แบบฟอร์ม ดังนั้นตามที่ Cerad ระบุไว้ฉันก็ชอบวิธีนี้มากกว่า คุณสามารถสร้างบริการเพื่อตั้งค่าเริ่มต้นเหล่านั้นและในตัวควบคุมใช้บริการที่ทำให้มันแห้ง
saamorim

นี่คือทางออกที่ฉันเลือกเพราะมันเหมาะกับตรรกะที่ฉันคิด ตัวควบคุมที่สร้างขึ้นมีวิธีการต่าง ๆ สำหรับการสร้างแบบฟอร์ม EDIT และ CREATE และเป็นที่ที่ฉันตั้งค่าข้อมูลเริ่มต้น / เริ่มต้นสำหรับเอนทิตีใหม่
alumi

1

ถ้าเขตข้อมูลนั้นถูกผูกไว้กับเอนทิตี (เป็นคุณสมบัติของเอนทิตีนั้น) คุณสามารถตั้งค่าเริ่มต้นให้กับมันได้

ตัวอย่าง:

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

1

โดยปกติฉันเพิ่งตั้งค่าเริ่มต้นสำหรับฟิลด์เฉพาะในเอนทิตีของฉัน:

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

วิธีนี้จะใช้งานได้กับระเบียนใหม่หรือหากเพิ่งอัปเดตรายการที่มีอยู่


สิ่งนี้ดูเหมือนจะไม่ทำงานเมื่อ'empty_data'มีการเรียกกลับถูกใช้เพื่ออนุญาตให้พารามิเตอร์คอนสตรัคเตอร์ในเอนทิตี
NDM

1

ดังที่ไบรอันถามว่า:

empty_data ปรากฏขึ้นเพื่อตั้งค่าฟิลด์เป็น 1 เท่านั้นเมื่อถูกส่งโดยไม่มีค่า สิ่งที่เกี่ยวกับเมื่อคุณต้องการรูปแบบเริ่มต้นที่จะแสดง 1 ในการป้อนข้อมูลเมื่อไม่มีค่าอยู่?

คุณสามารถตั้งค่าเริ่มต้นด้วย empty_value

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

0

ฉันแก้ไขปัญหานี้โดยการเพิ่มมูลค่าในattr :

->add('projectDeliveringInDays', null, [
    'attr' => [
          'min'=>'1',
          'value'=>'1'
          ]
     ])
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.