# Handling Laminas Forms with Dependencies - the view results

**URL:** <https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343>\
**Category:** Components & MVC\
**Tags:** laminas-form\
**Created:** [January 30, 2020, 12:15pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343 "2020-01-30T12:15:40Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pule](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/pule/32/600_2.png) [@Pule](https://discourse.laminas.dev/u/Pule)\
**Post date:** [January 30, 2020, 12:15pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/1 "2020-01-30T12:15:40Z")

</div>

I am developing a Laminas-Form that requires dependencies from a database table.

#My form looks like this:

```
namespace Application\Form;

use Laminas\Form\Form;

class CountryForm extends Form
{
    public function init()
    {
        parent::init();
	
        $this->add([
            'type' => CountryFieldset::class,
            'name' => 'country_id',
            'options' => [
                'use_as_base_fieldset' => true
            ]
        ]);
    }
}

```

#My Fieldset looks like this

```
namespace Application\Form;

use Application\Model\Table\CountriesTable;
use Laminas\Form\Element\Select;
use Laminas\Form\Fieldset;

class CountryFieldset extends Fieldset
{
    public function __construct(CountriesTable $countriesTable)
    {
        $countries = $countriesTable->fetchAllCountries();

        $selectField = new Select();
        $selectField->setName('country_id')
                    ->setOptions([
                        $selectField->setLabel('Countries'),
                        $selectField->setEmptyOption('Select...'),
                        $selectField->setValueOptions($countries);
                    ])
                    ->setAttributes([
                        'required' => true,
                        'class' => 'custom-select'
                     ]);

         $this->add($selectField);
    }
}

```

#Factory looks like this:

```
namespace Application\Form;

use Application\Model\Table\CountriesTable;
use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\FactoryInterface;
use Laminas\ServiceManager\ServiceLocatorInterface;

class CountryFieldsetFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $name, array $options = null)
    {
        return new CountryFieldset($container->get(CountriesTable::class));
    }
}

```

#My Controller Factory looks like this:

```
namespace Application\Controller;

use Interop\Container\ContainerInterface;
use Application\Form\CountryForm;

class IndexControllerFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $formManager = $container->get('FormElementManager');
        return new IndexController($formManager->get(CountryForm::class));
    }
}

```

#My controller looks like this:

```
namespace Application\Controller;

use Application\Form\MyForm;
use Laminas\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{
     private $countryForm;

    public function __construct(CountryForm $countryForm)
    {
        $this->countryForm = $countryForm;
    }

    public function indexAction()
    {
        return array('form' => $this->countryForm);
    }
}

```

#I mapped the fieldset factory to look like this in the module.config.php file:

```
return [
    'form_elements' => [
        'factories' => [
            Application\Form\CountryFieldset::class => Application\Form\CountryFieldsetFactory::class,
        ],
    ],
    'controllers' => [
        'factories' => [
            Application\Controller\IndexController::class => Application\Controller\IndexControllerFactory::class,
        ],
    ],
];

```

#My form view looks like

```
<?php
echo $this->form()->openTag($form);
echo $this->formCollection($form->get('country_id'));
echo $this->form()->closeTag();

```

As you can see everything works fine. The Select option values display as I would like them to.  
The issue I am having is that in the views the the select form attribute name comes up as  
‘country\_id[country\_id]’

```
 <fieldset>
    <label>
       <span>Countries</span>
          <select name="country_id[country_id]" required="required" class="custom-select">
              <option value="">Select...</option>
              <option value="1">Afghanistan</option>
                   .
                   .
                   .
          </select>
    </label>
</fieldset>  

```

as opposed to the expected attribute name of ‘country\_id’:

`<select name="country_id" required="required" class="custom-select">`

Can anyone help me understand why that is the case?

---

<div class="post-metadata">

**Author:** ![ocramius](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/ocramius/32/23_2.png) [@ocramius](https://discourse.laminas.dev/u/ocramius)\
**Post date:** [January 30, 2020, 12:42pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/2 "2020-01-30T12:42:36Z")

</div>

Hey Pule,

That’s most likely because your field is inside a fieldset, and therefore its name is nested to dis-ambiguate with other (potential) fieldsets. If you don’t like the prefix, put the select element directly into your CountryForm, not in the CountryFieldset

---

<div class="post-metadata">

**Author:** ![Pule](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/pule/32/600_2.png) [@Pule](https://discourse.laminas.dev/u/Pule)\
**Post date:** [January 30, 2020, 12:47pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/3 "2020-01-30T12:47:37Z")

</div>

Well thanks for the reply. My concern is about the name attribute not the arrangement of the form. That is i get attribute name of **country\_id[country\_id]** as opposed to the expected name of **country\_id**. I am not sure if i am clear. My concern is this

```auto
name="country_id[country_id]"

```

I expect this - **name=“country\_id”**.

---

<div class="post-metadata">

**Author:** ![ocramius](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/ocramius/32/23_2.png) [@ocramius](https://discourse.laminas.dev/u/ocramius)\
**Post date:** [January 30, 2020, 1:00pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/4 "2020-01-30T13:00:30Z")

</div>

Yeah, that’s exactly what I was referring to: the attribute name is using an array-like format because of how the element is placed under a nested fieldset.

---

<div class="post-metadata">

**Author:** ![Pule](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/pule/32/600_2.png) [@Pule](https://discourse.laminas.dev/u/Pule)\
**Post date:** [January 30, 2020, 1:04pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/5 "2020-01-30T13:04:26Z")

</div>

Alright. I read that really fast and I misunderstood you. I got what you meant after I replied to you. I am working on the solution now. Thanks for nudging me in the right direction. I will be sure to post how I resolved this issue as soon as I am done. Cheers.

---

<div class="post-metadata">

**Author:** ![Pule](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/pule/32/600_2.png) [@Pule](https://discourse.laminas.dev/u/Pule)\
**Post date:** [January 30, 2020, 4:18pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/6 "2020-01-30T16:18:59Z")

</div>

I resolved this issue by taking a rather ugly approach. This is how I did it:

```
namespace Application\Controller;

use Application\Model\Table\CountriesTable;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;

IndexController extends AbstractActionController
{
    private $countriesTable;
 
    public function __construct(CountriesTable $countriesTable)
    {
         $this->countriesTable = $countriesTable;
    }

    public function indexAction()
    {
        $countries = $this->countriesTable->fetchAllCountries();
        $selectField = new Select();
        $selectField->setName('country_id')
			->setOptions([
				$selectField->setLabel('Countries'),
				$selectField->setEmptyOption('Select...'),
				$selectField->setValueOptions($countries)
			])
			->setAttributes([
				'required' => true,
				'class' => 'custom-select'
			]);
		
	$createForm = new CreateForm();
	$createForm->add($selectField);

        $request = $this->getRequest();
        if ($request->isPost()) {
            #processing and saving data to the table goes here...
        }

       return new ViewModel(['form' => $createForm]);
    }
}
```

---

<div class="post-metadata">

**Author:** ![ddelrio1986](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/ddelrio1986/32/131_2.png) [@ddelrio1986](https://discourse.laminas.dev/u/ddelrio1986)\
**Post date:** [January 30, 2020, 4:29pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/7 "2020-01-30T16:29:43Z")

</div>

I wouldn’t advise building your form that way within an action. I would use the previous suggestion of getting rid of the fieldset entirely and just putting the select element directly in your form.

---

<div class="post-metadata">

**Author:** ![Pule](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/pule/32/600_2.png) [@Pule](https://discourse.laminas.dev/u/Pule)\
**Post date:** [January 30, 2020, 4:40pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/8 "2020-01-30T16:40:11Z")

</div>

I understood that suggestion. The issue is if I place the Select field in the CountryForm how would I fetch the database dependencies with the form set to init(). This is what I was running away from. I tried using the FactoryInterface in the CountryForm but did not get far with that.

---

<div class="post-metadata">

**Author:** ![ddelrio1986](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/ddelrio1986/32/131_2.png) [@ddelrio1986](https://discourse.laminas.dev/u/ddelrio1986)\
**Post date:** [January 30, 2020, 4:58pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/9 "2020-01-30T16:58:31Z")

</div>

You could use the technique shown in the docs here to create your form in a way that will allow you to inject dependencies with a factory: [https://docs.laminas.dev/laminas-form/quick-start/#factory-backed-form-extension](https://docs.laminas.dev/laminas-form/quick-start/#factory-backed-form-extension)

---

<div class="post-metadata">

**Author:** ![Pule](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/pule/32/600_2.png) [@Pule](https://discourse.laminas.dev/u/Pule)\
**Post date:** [January 30, 2020, 7:59pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/10 "2020-01-30T19:59:19Z")

</div>

Thank you @ [ddelrio1986](https://discourse.laminas.dev/u/ddelrio1986). It worked the way I wanted it to. I will put the final solution below so that others who may have the same issue as me may benefit. Once again thank you.

---

<div class="post-metadata">

**Author:** ![Pule](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/pule/32/600_2.png) [@Pule](https://discourse.laminas.dev/u/Pule)\
**Post date:** [January 30, 2020, 8:32pm UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/11 "2020-01-30T20:32:35Z")

</div>

**Final Working Solution**

#My CountryForm now looks as follows:

```
namespace Application\Form;

use Laminas\Form\Element;
use Laminas\Form\Form;

class CountryForm extends Form
{
    public function __construct(CountriesTable $countriesTable)
    {
        parent::__construct();
        $this->setAttribute('method', 'post');

        $this->add([
            'type' => Element\Select::class,
            'name' => 'country_id',
            'options' => [
                'label' => 'Countries',
                'value_options' => $categories->fetchAllCountries()
            ],
            'attributes' => [
                'required' => true,
                'class' => 'custom-select'
            ]
        ]);
    }
}

```

#My Application Module.php file is now updated to look thus:

```
namespace Application;

use Application\Form\CountryForm;
use Application\Model\Table\CountriesTable;
use Laminas\Db\Adapter\Adapter;

class Module
{
   public functon getConfig(): array{...}
   
   public function getServiceConfig()
   {
       return [
           'factories' => [
               CountriesTable::class => function($sm) {
                   $dbAdapter = $sm->get(Adapter::class);
                   return new CountriesTable($dbAdapter);
               }
           ]
       ];    
   }

   public function getFormElementConfig()
   {
       return [
           'factories' => [
               CountryForm::class => function($sm) {
                   $countriesTable = $sm->get(CountriesTable::class);
                   return new CountryForm($countriesTable);
               }
           ]
       ];
   }
}

```

#My Controller hasn’t changed

```
namespace Application\Controller;

use Application\Form\CountryForm;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;

class IndexController extends AbstractActionController
{
    protected $countryForm;

    public function __construct(CountryForm $countryForm)
    {
        $this->countryForm = $countryForm;
    }

    public function indexAction()
    {
        return new ViewModel(['form' => $this->countryForm]);
    }
}

```

#IndexControllerFactory looks like

```
namespace Application\Controller\Factory;

use Application\Controller\IndexController;
use Application\Form\CountryForm;
use Interop\Container\ContainerInterface;

class IndexControllerFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
	$formManager = $container->get('FormElementManager');
        return new IndexController(
            $formManager->get(CountryForm::class)
        );
    }
}

```

#My view looks like this:

```auto
<?php
echo $this->form()->openTag($form);
echo $this->formSelect($form->get('country_id'));
echo $this->form()->closeTag();

```

#My module.config.php file looks like this

```auto
return [
    'form_elements' => [
        'factories' => [
            Application\Form\CountryFieldset::class => Application\Form\CountryFieldsetFactory::class,
        ],
    ],
    'controllers' => [
        'factories' => [
            Application\Controller\IndexController::class => Application\Controller\IndexControllerFactory::class,
        ],
    ],
];

```

Hope this helps someone out there. Thanks to everyone who helped steer me in the right direction.  
Cheers.

---

<div class="post-metadata">

**Author:** ![froschdesign](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/froschdesign/32/38_2.png) [@froschdesign](https://discourse.laminas.dev/u/froschdesign)\
**Post date:** [January 31, 2020, 6:18am UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/12 "2020-01-31T06:18:37Z")

</div>

If only the select element needs entries from a database then you can create a separate form element with the required dependencies.

1. Create the element:

2. Create a factory for the element.

3. Register the new element:

4. Usage in a form:

This allows the element to be reused without factories for forms.

---

<div class="post-metadata">

**Author:** ![Pule](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/pule/32/600_2.png) [@Pule](https://discourse.laminas.dev/u/Pule)\
**Post date:** [January 31, 2020, 7:04am UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/13 "2020-01-31T07:04:18Z")

</div>

I am wondering about the MyForm code there. Wouldn’t you get an error because the name has not been defined. I had an issue where I wrote the code like you did in the MyForm and got an error regarding a name not found or something along those lines.

---

<div class="post-metadata">

**Author:** ![froschdesign](https://yyz2.discourse-cdn.com/flex032/user_avatar/discourse.laminas.dev/froschdesign/32/38_2.png) [@froschdesign](https://discourse.laminas.dev/u/froschdesign)\
**Post date:** [January 31, 2020, 7:06am UTC](https://discourse.laminas.dev/t/handling-laminas-forms-with-dependencies-the-view-results/1343/14 "2020-01-31T07:06:37Z")

</div>

The same applies here as for your fieldset, you must register the form element in your config under `form_elements`.

_I added the missing steps in my previous comment._
