Search code examples
phpdoctrinedropdownzend-formzend-framework3

Populate Multi select drop drop down zend 3


Hello everyone i am getting really hard time populating my multi select drop down in my form. what i have tried so far was adding factory for my form which is like this

class MovieFormFactory
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        $entityManager = $container->get('doctrine.entitymanager.orm_default');
        $actors = $entityManager->getRepository(Actor::class)->findAll();
        $form = new MovieForm();
        $form->setActors($data);

        
        return $form;
    }

}

my form

Class MovieForm extends Form
{

    private $actors = [];
    public function setActors($actorsData){ 
      $this->actors = $actors
    }
    public function __construct()
    {
        parent::__construct('post-form');

        $this->setAttribute('method', 'post');

        $this->addElements();
        $this->addInputFilter();
        

      $this->add([
        'type'  => 'select',
        'name' => 'actors',
        'attributes' => [
            'id' => 'actors',
            'multiple' => true
        ],
        'options' => [
            'label' => 'Actors',
            'value_options' => $this->actors,
        ],
    ]);

        $this->add([
            'type'  => 'select',
            'name' => 'directors',
            'attributes' => [
                'id' => 'directors',
            ],
            'options' => [
                'label' => 'Director',
                'value_options' => $this->getOptionForSelect($directors),
            ],
        ]);

    }

    /**
     * This method adds elements to form (input fields and submit button).
     */
    protected function addElements()
    {

        // Add "title" field
        $this->add([
            'type'  => 'text',
            'name' => 'title',
            'attributes' => [
                'id' => 'title'
            ],
            'options' => [
                'label' => 'Title',
            ],
        ]);

        // Add "description" field
        $this->add([
            'type'  => 'textarea',
            'name' => 'description',
            'attributes' => [
                'id' => 'description'
            ],
            'options' => [
                'label' => 'Description',
            ],
        ]);

        // Add "tags" field
//        $this->add([
//            'type'  => 'text',
//            'name' => 'actors',
//            'attributes' => [
//                'id' => 'actors',
//                'multiple' => 'multiple'
//            ],
//            'options' => [
//                'label' => 'Actors',
//                'value_options' => $this->getOptionForSelect(),
//            ],
//        ]);

        // Add "status" field
        $this->add([
            'type'  => 'select',
            'name' => 'status',
            'attributes' => [
                'id' => 'status'
            ],
            'options' => [
                'label' => 'Status',
                'value_options' => [
                    MovieStatusEnum::STATUS_DRAFT => MovieStatusEnum::STATUS_DRAFT,
                    MovieStatusEnum::STATUS_PUBLISHED => MovieStatusEnum::STATUS_PUBLISHED,
                ]
            ],
        ]);

        // Add the submit button
        $this->add([
            'type'  => 'submit',
            'name' => 'submit',
            'attributes' => [
                'value' => 'Create',
                'id' => 'submitbutton',
            ],
        ]);
    }

    /**
     * This method creates input filter (used for form filtering/validation).
     */
    private function addInputFilter()
    {

        $inputFilter = new InputFilter();
        $this->setInputFilter($inputFilter);

        $inputFilter->add([
            'name'     => 'title',
            'required' => true,
            'filters'  => [
                ['name' => 'StringTrim'],
                ['name' => 'StripTags'],
                ['name' => 'StripNewlines'],
            ],
            'validators' => [
                [
                    'name'    => 'StringLength',
                    'options' => [
                        'min' => 1,
                        'max' => 1024
                    ],
                ],
            ],
        ]);

        $inputFilter->add([
            'name'     => 'description',
            'required' => true,
            'filters'  => [
                ['name' => 'StripTags'],
            ],
            'validators' => [
                [
                    'name'    => 'StringLength',
                    'options' => [
                        'min' => 1,
                        'max' => 4096
                    ],
                ],
            ],
        ]);

        $inputFilter->add([
            'name'     => 'actors',
            'required' => true,
        ]);

        
    }

    private function getOptionForSelect($data)
    {
        foreach ($data as $person) {
            $selectData[$person->getId()] = $person->getName();
        }
        return $selectData;
    }

}

and this is my registered factory in module.config.php

 'form_elements' => [
        'factories' => [
            Form\MovieForm::class => Form\Factory\MovieFormFactory::class
        ]
    ],

but nothing seems to work i am unable to show my actors while creating a movie and unable to show selected actors while editing a movie can some please guide me here i am new to zend.


Solution

  • In the constructor, the line value_options' => $this->actors is wrong because $this->actors is not set yet. In your factory you write :

    $form = new MovieForm();
    $form->setActors($data);
    

    You must therefore declare the public method setActors() in the class MovieForm which will take care of setting up the options array.

    public function setActors($array)
    {
        $this->get('actors')->setValueOptions($array);
    }