2015-03-13 6 views
9

के साथ इकाई फॉर्म फ़ील्ड में मेरे पास एक फॉर्म परिभाषा है जो अब तक के महान क्षेत्र प्रकार entity का उपयोग करती है। विकल्प query_builder के साथ मैं अपने मानों का चयन करता हूं और प्रदर्शित होता है।सिम्फनी 2: रिक्त मूल्य

दुखद बात यह है कि, मुझे null डिफ़ॉल्ट मान, जैसे all (यह एक फ़िल्टर फ़ॉर्म है) प्रदर्शित करने की आवश्यकता है। मुझे entity विकल्प पसंद नहीं है क्योंकि मेरे पास डेटाबेस मान हैं और FormType डेटाबेस से क्वेरी नहीं करना चाहिए।

मेरा दृष्टिकोण अब तक एक कस्टम फ़ील्ड प्रकार को लागू करना था जो entity बढ़ाता है और सूची के शीर्ष पर एक शून्य प्रविष्टि जोड़ता है। फ़ील्ड प्रकार लोड और उपयोग किया जाता है लेकिन दुर्भाग्य से डमी मान प्रदर्शित नहीं होता है।

क्षेत्र परिभाषा:

$builder->add('machine', 'first_null_entity', [ 
    'label' => 'label.machine', 
    'class' => Machine::ident(), 
    'query_builder' => function (EntityRepository $repo) 
    { 
     return $repo->createQueryBuilder('m') 
      ->where('m.mandator = :mandator') 
      ->setParameter('mandator', $this->mandator) 
      ->orderBy('m.name', 'ASC'); 
    } 
]); 

प्रपत्र प्रकार परिभाषा:

class FirstNullEntityType extends AbstractType 
{ 

    /** 
    * @var unknown 
    */ 
    private $doctrine; 

    public function __construct(ContainerInterface $container) 
    { 
     $this->doctrine = $container->get('doctrine'); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setRequired('query_builder'); 
     $resolver->setRequired('class'); 
    } 

    public function buildView(FormView $view, FormInterface $form, array $options) 
    { 
     $class = $options['class']; 
     $repo = $this->doctrine->getRepository($class); 

     $builder = $options['query_builder']($repo); 
     $entities = $builder->getQuery()->execute(); 

     // add dummy entry to start of array 
     if($entities) { 
      $dummy = new \stdClass(); 
      $dummy->__toString = function() { 
       return ''; 
      }; 
      array_unshift($entities, $dummy); 
     } 

     $options['choices'] = $entities; 
    } 

    public function getName() 
    { 
     return 'first_null_entity'; 
    } 

    public function getParent() 
    { 
     return 'entity'; 
    } 
} 
+0

आप $ विकल्प [''] = 'All' का उपयोग कर सकते हैं; आपके फॉर्म प्रकार में परिभाषा –

उत्तर

3

एक वैकल्पिक दृष्टिकोण विकल्पों डेटाबेस से उत्पन्न कर रहे हैं के साथ एक ChoiceList का उपयोग और उसके बाद का उपयोग करें कि एक में होगा कस्टम पसंद फ़ॉर्म प्रकार जो empty_value के लिए अनुमति देगा।

विकल्प सूची

namespace Acme\YourBundle\Form\ChoiceList; 

use Doctrine\Common\Persistence\ObjectManager; 
use Symfony\Component\Form\Extension\Core\ChoiceList\LazyChoiceList; 
use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface; 
use Symfony\Component\Form\Extension\Core\ChoiceList\SimpleChoiceList; 

class MachineChoiceList extends LazyChoiceList 
{ 
    protected $repository; 

    protected $mandator; 

    public function __construct(ObjectManager $manager, $class) 
    { 
     $this->repository = $manager->getRepository($class); 
    } 

    /** 
    * Set mandator 
    * 
    * @param $mandator 
    * @return $this 
    */ 
    public function setMandator($mandator) 
    { 
     $this->mandator = $mandator; 

     return $this; 
    } 

    /** 
    * Get machine choices from DB and convert to an array 
    * 
    * @return array 
    */ 
    private function getMachineChoices() 
    { 
     $criteria = array(); 

     if (null !== $this->mandator) { 
      $criteria['mandator'] = $this->mandator; 
     } 

     $items = $this->repository->findBy($criteria, array('name', 'ASC')); 

     $choices = array(); 

     foreach ($items as $item) { 
      $choices[** db value **] = ** select value **; 
     } 

     return $choices; 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    protected function loadChoiceList() 
    { 
     return new SimpleChoiceList($this->getMachineChoices()); 
    } 
} 

विकल्प सूची सेवा (YAML)

acme.form.choice_list.machine: 
    class: Acme\YourBundle\Form\ChoiceList\MachineChoiceList 
    arguments: 
     - @doctrine.orm.default_entity_manager 
     - %acme.model.machine.class% 

कस्टम प्रपत्र प्रकार

namespace Acme\YourBundle\Form\Type; 

use Acme\YourBundle\Form\ChoiceList\MachineChoiceList; 
.. 

class FirstNullEntityType extends AbstractType 
{ 
    /** 
    * @var ChoiceListInterface 
    */ 
    private $choiceList; 

    public function __construct(MachineChoiceList $choiceList) 
    { 
     $this->choiceList = $choiceList; 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $choiceList = $this->choiceList; 

     $resolver->setDefault('mandator', null); 

     $resolver->setDefault('choice_list', function(Options $options) use ($choiceList) { 
      if (null !== $options['mandator']) { 
       $choiceList->setMandator($options['mandator']); 
      } 

      return $choiceList; 
     }); 
    } 

    public function getName() 
    { 
     return 'first_null_entity'; 
    } 

    public function getParent() 
    { 
     return 'choice'; 
    } 
} 

कस्टम प्रपत्र प्रकार सेवा (YAML)

acme.form.type.machine: 
    class: Acme\YourBundle\Form\Type\FirstNullEntityType 
    arguments: 
     - @acme.form.choice_list.machine 
    tags: 
     - { name: form.type, alias: first_null_entity } 

आपके फ़ॉर्म में

$builder 
    ->add('machine', 'first_null_entity', [ 
     'empty_value' => 'None Selected', 
     'label'   => 'label.machine', 
     'required'  => false, 
    ]) 
; 
+0

आपके महान उत्तर के लिए धन्यवाद। इस तरह, मुझे सेवा के रूप में 'मशीनChoiceList' और' FirstNullEntityType 'दोनों को पंजीकृत करना होगा और सूची को प्रकार में पास करना होगा, है ना? – Joshua

+0

हाँ, यह सही है। मैंने अपने उत्तरों को उन सेवाओं के वाईएएमएल संस्करणों के साथ अपडेट किया है। – qooplmao

+0

आपकी मदद के लिए धन्यवाद। मैंने 'चॉइसलिस्ट' को सीधे क्षेत्र के प्रकार में बनाया, क्योंकि यह मेरे लिए अधिक लचीला प्रतीत होता है। जैसा कि आपने सुझाव दिया था 'कुंजी' फ़ील्ड का विस्तार करना था। – Joshua

24

यहाँ प्लेसहोल्डर उपयोग कर सकते हैं क्या Symfony में 3.0.3

काम करता है

use Symfony\Bridge\Doctrine\Form\Type\EntityType;

$builder->add('example' EntityType::class, array(
    'label' => 'Example', 
    'class' => 'AppBundle:Example', 
    'placeholder' => 'Please choose', 
    'empty_data' => null, 
    'required' => false 
)); 
+2

के साथ काम नहीं करता प्रतीत होता है' empty_data => null' ChoiceType के साथ काम नहीं करेगा – dompie