简体   繁体   中英

How to load select option from database in zf2

I Have been following zf2 guide for blog I have created everything Controller, Factory, Form, Mapper, Model, Service, view etc

In my form I have a select element

$this->add(array(     
  'type' => 'select',       
  'name' => 'roleId',
  'attributes' =>  array(
    'id' => 'roleId',
    'options' => array(
        '1' => 'Admin',
        '2' => 'Manager',
    ),
  ),
  'options' => array(
    'label' => 'Role',
  ),
));

Now in this form I want to load the option for the role from the database.
I tried loading the option by creating a simple function, which can be accessed in the element as below, but Am not able to fetch the result. I have already created Controller, Factory, Form, Mapper, Model, Service and view, Where I can do CRUD operation on Role.

$this->add(array(     
  'type' => 'select',       
  'name' => 'roleId',
  'attributes' =>  array(
    'id' => 'roleId',
    'options' => $this->getAllRoles(),
  ),
  'options' => array(
    'label' => 'Role',
  ),
));

public function getAllRoles()
{
  $roles = $this->getServiceLocator()->get('Admin\Service\RoleService');
  $allRoles = $this->getAllTheRoles();  
  return $allroles;
}

Can anybody guide me how can I load all the Roles in option as listed in the IndexAction following Blog Post with ID and Name of the Role.

You could create a reusable form element that is pre-populated with the roles. To do so you must register the service with the form element manager in module.config.php .

return [
    'form_elements' => [
        'factories' => [
            'RoleSelect' => 'MyModule\Form\Element\RoleSelectFactory',
        ],
    ],
];

There is not need to extend the standard select class as the changes are configuration only. This is best done in a factory class.

namespace MyModule\Form\Element;

use Zend\Form\Element\Select;

class RoleSelectFactory
{
    public function __invoke($formElementManager, $name, $rname)
    {
        $select = new Select('role_id');

        $select->setOptions(['label' => 'Role']);
        $select->setAttributes(['id' => 'role_id']);

        $serviceManager = $formElementManager->getServiceLocator();
        $roleService = $serviceManager->get('Admin\Service\RoleService');

        $options = [];
        foreach($roleService->getAllTheRoles() as $role){
            $options[$role->getId()] => $role->getName();
        }

        $select->setValueOptions($options);

        return $select;
    }
}

Adding the element within a form can then be updated to use the name of the service we registered.

$this->add([     
    'name' => 'role_id'
    'type' => 'RoleSelect',       
]);

One important point to remember is that the form using this element must be created using the $formElementManager->get('FormWithRoleSelect') .

Finally found out the simple way to do this, Am really not sure if this is the correct way.

Added the Role service in the User Controller

Code in my userController.php

use Admin\Service\RoleServiceInterface;
class UserController extends AbstractActionController
{
  /**
  * @var \Admin\Service\UserServiceInterface
  */
  protected $userService;
  protected $roleService;
  protected $userForm;

  public function __construct(
    UserServiceInterface $userService,
    RoleServiceInterface $roleService,
    FormInterface $userForm
  )
  {
    $this->userService = $userService;
    $this->roleService = $roleService;
    $this->userForm    = $userForm;
  }

  public function addAction()
  {
    $request = $this->getRequest();
    $roles    = $this->roleService->findAllRoles();
    foreach ($roles as $role) {
      if($role->getStatus() == 1) {
        $allRoles[$role->getId()] = $role->getName();
      }
    }
    $this->userForm->__construct(null, array('roleOptions'=>$allRoles));
  }
}

My UserControllerFactory.php

<?php

namespace Admin\Factory;

use Admin\Controller\UserController;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class UserControllerFactory implements FactoryInterface
{
  /**
  * Create service
  *
  * @param ServiceLocatorInterface $serviceLocator
  *
  * @return mixed
  */
  public function createService(ServiceLocatorInterface $serviceLocator)
  {
    $realServiceLocator = $serviceLocator->getServiceLocator();
    $userService        = $realServiceLocator->get('Admin\Service\UserServiceInterface');
    $roleService        = $realServiceLocator->get('Admin\Service\RoleServiceInterface');
    $userInsertForm     = $realServiceLocator->get('FormElementManager')->get('Admin\Form\UserForm');

    return new UserController(
    $userService,
    $roleService,
    $userInsertForm
    );
  }
}

Finally the UserForm.php

<?php

namespace Admin\Form;

use Zend\Form\Form;
use Admin\Model\User;
use Zend\Stdlib\Hydrator\ClassMethods;
use Zend\Form\Element\Select;


class UserForm extends Form
{
  public function __construct($name = null, $options = array())
  {
    $roleOptions = array();
    if($options) {
      $roleOptions = $options['roleOptions'];
    }
    parent::__construct($name, $options);

    $this->setHydrator(new ClassMethods(false));
    $this->setObject(new User());
    $this->add(array(
      'type' => 'hidden',
      'name' => 'id'
    ));

   $this->add(array(     
     'type' => 'select',       
     'name' => 'roleId',
     'attributes' =>  array(
       'id' => 'roleId',
       'options' => $roleOptions
     ),
    'options' => array(
      'label' => 'Role',
    ),
    ));
  }
}

This way using service manager I was successfully able to load the data in my for Select option.

Call getAllRoles() inside the controller then You can pass your custom array as parameter for form when you create form object. In form __construct function you can retrieve that array and set like this

'options' => $roles,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM