Search code examples
zend-framework2zend-form2

How to get data from different model for select?


I have form with some attributes:

class ToraForm extends Form
{
    public function __construct($name = null)
    {
        parent::__construct('tora');
        $this->setAttribute('method', 'post');

        $this->add(array(
            'name' => 'id',
            'attributes' => array(
                'type' => 'hidden',
            ),
        ));
        $this->add(array(
            'name' => 'name',
            'attributes' => array(
                'type' => 'text',
                'required' => true,
            ),
            'options' => array(
                'label' => 'name',
            ),
        ));
}

but I want add drop-down list with data taken from another model. How to do it?


Solution

  • There are several different approaches you can take. Ultimately your Form has a dependency, which needs to be injected. I have written an in-depth blog-post about the three most common use-cases for Form-Dependencies for a Select-List.

    My BlogPost covers the following scenarios:

    • Zend\Form\Element\Select via DbAdapter
    • Zend\Form\Element\Select via TableGateway
    • DoctrineModule\Form\Element\DoctrineObject via Doctrine2

    Here i will demonstrate only the DbAdapter approach without much explanation. Please refer to my blogpost for the in-depth explanations.

    public function formDbAdapterAction()
    {
        $vm = new ViewModel();
        $vm->setTemplate('form-dependencies/form/form-db-adapter.phtml');
    
        $dbAdapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
        $form      = new DbAdapterForm($dbAdapter);
    
            return $vm->setVariables(array(
            'form' => $form
        ));
    }
    

    Then the respective Form Class:

    class DbAdapterForm extends Form
    {
        protected $dbAdapter;
    
        public function __construct(AdapterInterface $dbAdapter)
        {
            $this->setDbAdapter($dbAdapter);
    
            parent::__construct('db-adapter-form');
    
            $this->add(array(
                'name'    => 'db-select',
                'type'    => 'Zend\Form\Element\Select',
                'options' => array(
                    'label'         => 'Dynamic DbAdapter Select',
                    'value_options' => $this->getOptionsForSelect(),
                    'empty_option'  => '--- please choose ---'
                )
            ));
        }
    
        // more later...
    
        // Also: create SETTER and GETTER for $dbAdapter!
    }
    

    And last but not least the DataProvider function:

    public function getOptionsForSelect()
    {
        $dbAdapter = $this->getDbAdapter();
        $sql       = 'SELECT t0.id, t0.title FROM selectoptions t0 ORDER BY t0.title ASC';
        $statement = $dbAdapter->query($sql);
        $result    = $statement->execute();
    
        $selectData = array();
    
        foreach ($result as $res) {
            $selectData[$res['id']] = $res['title'];
        }
    
        return $selectData;
    }