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



(18)

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


Answers

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

// 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 हमेशा डिफ़ॉल्ट मान पर सेट हो जाएगा।


मेरा समाधान:

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

एक बहुत ही सरल तरीका है, आप यहां डिफ़ॉल्ट रूप से सेट कर सकते हैं:

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

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

उपयोग न करें:

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

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

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

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

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

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


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

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

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

});

अक्सर, फॉर्म के 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',
));

यदि आप अपने सृजन फ़ॉर्म में 'डेटा' सेट करते हैं, तो यह मान आपकी इकाई को संपादित करते समय संशोधित नहीं किया जाएगा।

मेरा समाधान है:

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

अलविदा।


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

एक उदाहरण:

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

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

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

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

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

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

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

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

मैंने अतीत में कुछ बार इस पर विचार किया है, इसलिए मैंने सोचा कि मैंने अलग-अलग विचारों को कम कर दिया है। कुछ उपयोग हो सकता है, लेकिन कोई भी "सही" 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') का उपयोग किया है, क्योंकि मुझे इसकी आवश्यकता है।

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

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


डिफ़ॉल्ट मान को संबंधित इकाई को कॉन्फ़िगर करके सेट किया जाता है। इकाई को बाध्य करने से पहले अपने रंग क्षेत्र को "# 0000FF" पर सेट करने के लिए:

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

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

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

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

आप गुणों को CURRENT_TIMESTAMP पर अपडेट कर सकते हैं और वर्तमान समय स्टैम्प के लिए डिफ़ॉल्ट रूप से क्वेरी के माध्यम से अपडेट किए बिना स्वचालित समय स्टाम्प को स्वचालित रूप से अपडेट कर देंगे

`feildname` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP




php symfony