php - Symfony2 में फॉर्म फ़ील्ड के लिए डिफ़ॉल्ट मान कैसे सेट करें?




(14)

क्या टेक्स्ट फॉर्म फ़ील्ड के लिए डिफ़ॉल्ट मान सेट करने का कोई आसान तरीका है?


अक्सर, फॉर्म के init डिफ़ॉल्ट मानों के लिए मैं फिक्स्चर का उपयोग करता हूं। इस तरह से सबसे आसान नहीं है, लेकिन बहुत आरामदायक है।

उदाहरण:

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();        
    }   
}

फिर भी, सिम्फनी प्रकार फ़ील्ड में विकल्प data

उदाहरण

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

आप empty_data साथ डिफ़ॉल्ट मान सेट कर सकते हैं

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

आप एक डिफ़ॉल्ट मान सेट कर सकते हैं, उदाहरण के लिए फॉर्म 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();

आसानी से निर्माण के दौरान उपयोग किया जा सकता है:

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

किसी भी मामले / दृष्टिकोण के लिए मुख्य समाधान, मुख्य रूप से कक्षा के बिना किसी फॉर्म का उपयोग करके या जब हमें डिफ़ॉल्ट मान निर्धारित करने के लिए किसी भी सेवा तक पहुंच की आवश्यकता होती है:

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

जैसा ब्रायन ने पूछा:

खाली_डेटा केवल फ़ील्ड को 1 पर सेट करने के लिए प्रतीत होता है जब इसे कोई मान नहीं दिया जाता है। जब कोई मूल्य मौजूद नहीं होता है तो इनपुट में 1 प्रदर्शित करने के लिए जब आप डिफ़ॉल्ट रूप से फॉर्म को डिफ़ॉल्ट रूप से देखना चाहते हैं तो क्या होगा?

आप empty_value साथ डिफ़ॉल्ट मान सेट कर सकते हैं

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

दृष्टिकोण 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, और सिमफनी 2 में फॉर्म फ़ील्ड के लिए डिफ़ॉल्ट मान कैसे सेट करें से दिमित्री का जवाब (स्वीकार नहीं किया गया) भी ?

फॉर्म्रिल्डर के साथ फ़ील्ड जोड़ते समय डेटा विशेषता में डिफ़ॉल्ट मान जोड़ें, जिसे दिमित्री के उत्तर से अनुकूलित किया गया है।

ध्यान दें कि यह मानता है कि संपत्ति केवल तभी होगी जब यह एक नई हो, न कि मौजूदा, इकाई हो।

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

बस मैं समस्या को समझता हूं।

आप अपनी इकाई के डेटा के आधार पर फ़ॉर्म को जिस तरह से बनाया गया है उसे समायोजित करना चाहते हैं। यदि इकाई बनाई जा रही है तो कुछ डिफ़ॉल्ट मान का उपयोग करें। यदि इकाई मौजूदा है तो डेटाबेस मान का उपयोग करें।

व्यक्तिगत रूप से, मुझे लगता है कि @ आणविक मनुष्य का समाधान जाने का रास्ता है। मैं वास्तव में कन्स्ट्रक्टर या संपत्ति विवरण में डिफ़ॉल्ट मान निर्धारित करता हूं। लेकिन आप उस दृष्टिकोण को पसंद नहीं करते हैं।

इसके बजाय आप इसका अनुसरण कर सकते हैं: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

आप अपने फॉर्म प्रकार पर एक श्रोता लटकाते हैं और फिर आप अपनी इकाई की जांच कर सकते हैं और बिल्डर को समायोजित कर सकते हैं-> एक नया या मौजूदा इकाई हैविन के आधार पर बयान जोड़ें। आपको अभी भी अपने डिफ़ॉल्ट मान कहीं निर्दिष्ट करने की आवश्यकता है, हालांकि आप उन्हें अपने श्रोता में कोड कर सकते हैं। या उन्हें फॉर्म प्रकार में पास करें।

हालांकि बहुत सारे काम की तरह लगता है। पहले से सेट किए गए डिफ़ॉल्ट मानों के साथ इकाई को फ़ॉर्म में पास करने के लिए बेहतर है।


मैं आमतौर पर बस अपनी इकाई में विशिष्ट फ़ील्ड के लिए डिफ़ॉल्ट मान सेट करता हूं:

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

यह नए रिकॉर्ड के लिए काम करेगा या अगर मौजूदा लोगों को अपडेट कर रहा है।


मैंने अतीत में कुछ बार इस पर विचार किया है, इसलिए मैंने सोचा कि मैंने अलग-अलग विचारों को कम कर दिया है। कुछ उपयोग हो सकता है, लेकिन कोई भी "सही" Symfony2 समाधान नहीं है।

इकाई में रचनाकार आप $-- setBar ('डिफ़ॉल्ट मान') कर सकते हैं; लेकिन हर बार जब आप इकाई लोड करते हैं (डीबी या नहीं) कहा जाता है और थोड़ा गन्दा होता है। हालांकि यह प्रत्येक फ़ील्ड प्रकार के लिए काम करता है क्योंकि आप तिथियां बना सकते हैं या जो कुछ भी आपको चाहिए।

यदि प्राप्त करने के भीतर बयान मैं नहीं करता, लेकिन आप कर सकते हैं।

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

कारखाना / उदाहरण । एक स्थिर फ़ंक्शन / द्वितीयक वर्ग पर कॉल करें जो आपको डेटा के साथ पूर्व-जनसंख्या वाली डिफ़ॉल्ट इकाई प्रदान करता है। उदाहरण के लिए

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

   return $obj;
}

वास्तव में आदर्श नहीं है यदि आप अतिरिक्त फ़ील्ड जोड़ते हैं तो आपको यह फ़ंक्शन बनाए रखना होगा, लेकिन इसका मतलब यह है कि आप डेटा सेटर्स / डिफ़ॉल्ट को अलग कर रहे हैं और जो डीबी से उत्पन्न होता है। इसी प्रकार आप कई प्राप्त कर सकते हैं कारखानों को आप अलग-अलग डिफ़ॉल्ट डेटा चाहते हैं।

विस्तारित / प्रतिबिंब संस्थाएं एक विस्तारित इकाई बनाएं (उदाहरण के लिए FooCreate Foo को विस्तारित करता है) जो आपको समय (निर्माणकर्ता के माध्यम से) पर डिफ़ॉल्ट डेटा देता है। फैक्ट्री / इंस्टेंस विचार के समान ही एक अलग दृष्टिकोण - मैं व्यक्तिगत रूप से स्थिर तरीके पसंद करता हूं।

फॉर्म बनाने से पहले डेटा सेट करें कन्स्ट्रक्टर / सेवा में, आप जानते हैं कि क्या आपकी कोई नई इकाई है या यदि यह डीबी से पॉप्युलेट की गई है। इसलिए जब आप एक नई इकाई लेते हैं तो अलग-अलग क्षेत्रों पर सेट डेटा को कॉल करने के लिए यह संभव है। उदाहरण के लिए

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

फॉर्म इवेंट्स जब आप फॉर्म बनाते हैं तो आप फ़ील्ड बनाते समय डिफ़ॉल्ट डेटा सेट करते हैं। आप प्रीसेटडेटा ईवेंट श्रोता के इस उपयोग को ओवरराइड करते हैं। इसके साथ समस्या यह है कि आप फॉर्म वर्कलोड / डुप्लिकेटिंग कोड को डुप्लिकेट कर रहे हैं और इसे बनाए रखने / समझने के लिए कठिन बना रहे हैं।

विस्तारित रूप फॉर्म इवेंट के समान हैं, लेकिन यदि आप एक डीबी / नई इकाई है तो आप अलग-अलग प्रकार को कॉल करते हैं। इसके द्वारा मेरा मतलब है कि आपके पास FooType है जो आपके संपादन फ़ॉर्म को परिभाषित करता है, बारटाइप इसे FooType बढ़ाता है और सभी डेटा फ़ील्ड में सेट करता है। अपने नियंत्रक में आप बस चुनें कि किस फॉर्म प्रकार को बढ़ावा देना है। यह बेकार है अगर आपके पास कस्टम थीम है और घटनाओं की तरह, मेरी पसंद के लिए बहुत अधिक रखरखाव बनाता है।

टवीग आप अपनी खुद की थीम बना सकते हैं और मूल्य विकल्प का उपयोग कर डेटा को डिफॉल्ट कर सकते हैं जब आप इसे प्रति-फ़ील्ड आधार पर करते हैं। इसे किसी फ़ॉर्म थीम में लपेटने से रोकने के लिए कुछ भी नहीं है या तो आप अपने टेम्पलेट को साफ रखना चाहते हैं और फ़ॉर्म पुन: प्रयोज्य होना चाहिए। जैसे

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

जेएस फ़ील्ड खाली होने पर जेएस फ़ंक्शन के साथ फ़ॉर्म को पॉप्युलेट करना छोटा होगा। उदाहरण के लिए आप प्लेसहोल्डर के साथ कुछ कर सकते हैं। हालांकि यह एक बुरा, बुरा विचार है।

एक सेवा के रूप में फॉर्म मैंने किए गए बड़े फॉर्म आधारित परियोजनाओं में से एक के लिए, मैंने एक सेवा बनाई जिसने सभी रूपों को उत्पन्न किया, सभी प्रसंस्करण आदि किया। ऐसा इसलिए था क्योंकि कई वातावरणों में कई नियंत्रकों में रूपों का उपयोग किया जाना था और फॉर्म उसी तरह से उत्पन्न / संभाले गए थे, वे अलग-अलग प्रदर्शित किए गए / इंटरैक्ट किए गए थे (जैसे त्रुटि प्रबंधन, पुनर्निर्देशन आदि)। इस दृष्टिकोण की सुंदरता यह थी कि आप डिफ़ॉल्ट डेटा कर सकते हैं, जो कुछ भी आपको चाहिए, वह सामान्य रूप से त्रुटियों को संभालें और यह सब एक ही स्थान पर encapsulated है।

निष्कर्ष जैसा कि मैंने इसे देखा है, आप एक ही समस्या को समय और समय में फिर से चलाएंगे - डिफ़ॉल्ट डेटा कहाँ रहने के लिए है?

  • यदि आप इसे डीबी / सिद्धांत स्तर पर संग्रहीत करते हैं तो क्या होता है यदि आप हर बार डिफॉल्ट स्टोर नहीं करना चाहते हैं?
  • यदि आप इसे एंटीटी स्तर पर संग्रहीत करते हैं तो क्या होता है यदि आप उस इकाई को कहीं और डेटा के बिना फिर से उपयोग करना चाहते हैं?
  • यदि आप इसे एंटीटी लेवल पर स्टोर करते हैं और एक नया फ़ील्ड जोड़ते हैं, तो क्या आप पिछले संस्करणों को संपादन पर डिफ़ॉल्ट मान रखना चाहते हैं? डीबी में डिफ़ॉल्ट के लिए ही चला जाता है ...
  • यदि आप इसे फॉर्म स्तर पर संग्रहीत करते हैं, तो क्या यह स्पष्ट है जब आप कोड को बाद में बनाए रखने के लिए आते हैं?
  • यदि यह कन्स्ट्रक्टर में है तो क्या होता है यदि आप कई स्थानों पर फॉर्म का उपयोग करते हैं?
  • यदि आप इसे जेएस स्तर पर दबाते हैं तो आप बहुत दूर चले गए हैं - डेटा को जेएस को कभी भी ध्यान में नहीं रखना चाहिए (और हम संगतता को अनदेखा कर रहे हैं, त्रुटियों को प्रस्तुत करते हैं आदि)
  • सेवा बहुत बढ़िया है यदि आप मुझे पसंद करते हैं तो आप इसे कई स्थानों पर उपयोग कर रहे हैं, लेकिन यह एक साइट पर एक साधारण ऐड / एडिट फॉर्म के लिए ओवरकिल है ...

इसके लिए, मैंने हर बार अलग-अलग समस्या से संपर्क किया है। उदाहरण के लिए, फॉर्म बनाने से पहले एक साइनअप फॉर्म "न्यूजलेटर" विकल्प आसानी से (और तार्किक रूप से) कन्स्ट्रक्टर में सेट किया गया है। जब मैं फॉर्म संग्रह बना रहा था जो एक साथ जुड़े थे (उदाहरण के लिए विभिन्न प्रकार के रेडियो बटन एक साथ जुड़े हुए हैं) तो मैंने इवेंट श्रोताओं का उपयोग किया है। जब मैंने एक और जटिल इकाई बनाई है (उदाहरण के लिए, जिसमें बच्चों या डिफॉल्ट डेटा के बहुत सारे आवश्यक हैं) मैंने इसे तत्व बनाने के लिए एक फ़ंक्शन (उदाहरण के लिए 'getFactory') का उपयोग किया है, क्योंकि मुझे इसकी आवश्यकता है।

मुझे नहीं लगता कि एक बार "सही" दृष्टिकोण है क्योंकि हर बार जब मुझे यह आवश्यकता होती है तो यह थोड़ा अलग होता है।

सौभाग्य! मुझे आशा है कि मैंने आपको किसी भी दर पर विचार के लिए कुछ खाना दिया है और बहुत ज्यादा रैमबल नहीं किया है;)


यदि आप प्रपत्र उत्पन्न करने के लिए FormBuilder 2.7 में FormBuilder का उपयोग कर रहे हैं, तो आप createFormBuilder के createFormBuilder विधि में प्रारंभिक डेटा भी पास कर सकते हैं

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

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

यदि आपका फॉर्म किसी इकाई से जुड़ा हुआ है, तो केवल निर्माण विधि का उपयोग करके इकाई पर डिफ़ॉल्ट मान सेट करें:

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

यदि वह फ़ील्ड किसी इकाई से जुड़ी है (उस इकाई की एक संपत्ति है) तो आप इसके लिए डिफ़ॉल्ट मान सेट कर सकते हैं।

एक उदाहरण:

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

उपयोग न करें:

'data' => 'Default value'

यहां पढ़ें: https://symfony.com/doc/current/reference/forms/types/form.html#data

"डेटा विकल्प हमेशा प्रतिपादन करते समय डोमेन डेटा (ऑब्जेक्ट) से लिया गया मान ओवरराइड करता है। इसका मतलब यह है कि जब फॉर्म पहले से ही जारी ऑब्जेक्ट को संपादित करता है तो ऑब्जेक्ट वैल्यू भी ओवरराइड होता है, जिससे फॉर्म सबमिट होने पर इसे अपना निरंतर मान खो देता है।"

निम्न का उपयोग करें:

आइए कहें, इस उदाहरण के लिए, आपके पास एंटिटी फू है, और वहां एक क्षेत्र "सक्रिय" है (इस उदाहरण में चेकबॉक्स टाइप है, लेकिन प्रक्रिया हर दूसरे प्रकार के समान है), जिसे आप डिफ़ॉल्ट रूप से चेक करना चाहते हैं

आपके 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())) $data->setActive(true);
        }
   );
}
public function configureOptions( OptionsResolver $resolver )
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle:Foo',
    ));
}




symfony