Retrieve form parameter into fieldset

Hi,
I have passed parameters when calling my form in my controller. My form contains a fieldset in wich I need to retrieve data from table according the passed parameters in my form.
How can I get those parameters ?

Here is my action in my controller :

namespace Application\Controller;

use InvalidArgumentException;

use Commun\Form\Modules\Application\RealisationImpactForm;
use Commun\Model\Entity\Projet;
use Commun\Model\Entity\Supervision;
use Laminas\Hydrator\ArraySerializableHydrator;
use Commun\Controller\NslabsAbstractController;
use Laminas\View\Model\ViewModel;

class SupervisionController extends NslabsAbstractController
{
    public function realisationImpactAction(){
        $post=$this->post;  
        $mapperProjet = $this->SM->get('TPROJET');
        $mapperDoc = $this->SM->get('TDOC');
        //$hydrator = new ArraySerializableHydrator();
        //$reflectionHydrator = new \Laminas\Hydrator\ReflectionHydrator();
        $supervision  = new Supervision();
        
        $id = (int) $this->params()->fromRoute('id');       
        if (0 === $id) {              
            return $this->redirect()->toRoute('front-supervision',['action' =>  'edition-projet','id' => $id]);
        }
        
        $projet = $mapperProjet->fetchRow(['idProjet' => $id]);
        $docs = $mapperDoc->getDocsByProjetId($id);
        
        $realisationImpactForm = $this->formManager->get(RealisationImpactForm::class,['idProjet' => $id,'idSupervision' => 1]);     
        
        //$realisationImpactForm->bind($supervision)->setInputFilter($supervision->getInputFilter())->setData($post);         
        if(!$post){
            return new ViewModel(['form' => $realisationImpactForm,'user' => $this->user,'id' => $id,'projet' => $projet,'docs' => $docs]);
        }                
              
    }
        
}

Here is my form :

namespace Commun\Form\Modules\Application;

use Commun\Form\Modules\Application\Fieldset\RealisationImpactFieldset;

use Commun\Form\CommunForm;

class RealisationImpactForm extends CommunForm 
{
    
    /*private $params;
    public function __construct($params) {
        $this->params = $params;
        parent::__construct('RealisationImpactForm',$this->params);
        
        
    }*/
    public function init() {                
        $this->setName('RealisationImpactForm');        
        $this->addFieldset(RealisationImpactFieldset::class,['use_as_base_fieldset' => true,'params' => $this->params]);
        $this->addSubmitButton('next', 'Poursuivre', 'next', 'btn btn-vert w-100');        
        $this->addSubmitButton('previous', 'Retour', 'previous', 'btn btn-rouge w-100');
    }  
  
}

Here is my fieldset :

namespace Commun\Form\Modules\Application\Fieldset;

use Commun\Model\Entity\Supervision;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Hydrator\ReflectionHydrator;

use Commun\Form\CommunFormFieldset;


class RealisationImpactFieldset extends CommunFormFieldset implements InputFilterProviderInterface
{
    private $mapper;
    /*private $idProjet;
    private $idSupervision;*/
       
    public function __construct($mappers=[],$options=[])
    {       
        
        $this->mapper = $mappers;
        /*$this->idProjet = $idProjet;
        $this->idSupervision = $idSupervision;*/ 
        parent::__construct('RealisationImpactForm',$options);          
        $this->setHydrator(new ReflectionHydrator());
        $this->setObject(new Supervision());
        $this->setLabel('Realisation Impact');                  
    }
    
    public function init() {
        parent::init();   
        
        //$effets = $this->mapper['supervision']->getRapportEffetByProjetForSuivi($this->idProjet,$this->idSupervision);
        
        
        /*$this->addText('libelle','Intitulé de l\'activité','libelle',['class' => 'form-control champ-requis']);
        $options = $this->mapper['indicateur']->getOptions('idRefIndicateur','libelle','Aucune valeur choisie',null,['libelle']);           
        $this->addSelect('idRefIndicateur','Indicateur de performance',$options,['class' => 'form-control']);
        $this->addText('valeurReference','Valeur de référence','valeurReference',['class' => 'form-control champ_decimal']);
        $this->addText('valeurCible','Valeur cible','valeurCible',['class' => 'form-control champ_decimal']);
        $this->addTextarea('moyenVerification', 'Moyen de vérification', 'moyenVerification', ['class' => 'form-control','rows' => 3]); 
        $this->addTextarea('risqueMesureAttenuation', 'Risques et mesures d\'atténuation', 'risqueMesureAttenuation', ['class' => 'form-control','rows' => 3]);  */        
    }
        
    /**
     * @return array
     */
    public function getInputFilterSpecification()
    {
        return [
            
        ];
    }
}

I need to say that in my form, when I make a var_dump, I see the parameters but I do not know how to get them in the fieldset.

Thanks for any reply

The first problem I see here: setting the value options via some mappers. This should be removed from the forms and fieldsets.
Create custom elements or a custom select which gets the mapper name and field as options to fetch the value options. Otherwise you always have to drag the mappers through all the forms and fieldsets.


The constructor looks good in your form:

public function __construct($params)
{
    $this->params = $params;
    parent::__construct();
}

Or use the options:

public function __construct($params)
{
    parent::__construct(null, ['my_params' => $params]);
    // or
    parent::__construct();
    $this->setOption('my_params', $params);
}

Another way is a custom factory for your form:

final class FormFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, ?array $options = null)
    {
        $form = new $requestedName();
        if ($options !== null) {
            $form->setOptions($options);
        }

        return $form;
    }
}

Here you can overwrite the setOptions method of your form and do what you want.

In your fieldset you also can use the options because these can be set when adding:

$this->add(
    [
        'name'    => 'example_fieldset',
        'type'    => Laminas\Form\Fieldset::class,
        'options' => [
            'my_params' => $this->getOption('my_params'),
        ],
        // …
    ]
);

In your fieldset:

$params = $this->getOption('my_params');

Thank uou @froschdesign , I will test it and keep you posted.

The options of an element / fieldset / form are called “custom options” therefore this suggestion:

1 Like

I tried this and did not get params values in my fieldset :
Here is my Global form wich each form extends

<?php

/**
    * @module     Commun
    * @subpackage Form
    * @author     Samuel NANGUI <nanguisamuel@gmail.com>
    * @copyright  Copyright (c) 2020 Nslabs
    */

namespace Commun\Form;

use Laminas\Form\Form;
use Laminas\Hydrator\ClassMethodsHydrator;
use Laminas\InputFilter\InputFilter;
use Laminas\Form\Element\Select;
use Laminas\Form\Element\Hidden;

class CommunForm extends Form
{
    protected $mapper;
    public $params;
    public function __construct($formName=null,$params=[],$mapper=[]) {
        parent::__construct($formName);
        $this->mapper = $mapper;
        $this->params = $params;
        $this->setHydrator(new ClassMethodsHydrator(false));
        $this->setInputFilter(new InputFilter());
        $this->setAttribute('class', 'form-horizontal'); 
        $this->setOption('params', $params);
    }
    
    public function populateSelect(\Laminas\Form\Element\Select $selectName,$optionValues=[]){
        $selectName->setValueOptions($optionValues);
    }
    
    public function addFieldset($fieldset,$options=[]){        
        $this->add([
            'type' => $fieldset,
            'options' => $options,            
        ]);               
    }
    
    public function addSubmitButton($name,$label,$id='',$className=''){
        $this->add([
            'name' => $name,            
            'type'  => 'submit',            
            'attributes' => [
               'value' => $label,
               'id' =>  $id,
               'class' => $className,
           ]
        ]);        
    }
    
    
    public function addSelect($name,$label){
        $this->add([            
            'name' => $name,
            'type' => Select::class,
            'options' => [
                'label' => $label,
                'value_options' => [
                    '0' => 'French',
                    '1' => 'English',
                    '2' => 'Japanese',
                    '3' => 'Chinese',
                ],
            ],
        ]);
    }
    
    public function addFile($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'file',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],            
            'attributes' => $attributes,
        ]);
    }
    
    public function addHiddenElement($name,$attributes=[]){
        $this->add([
            'name' => $name,
            'type' => Hidden::class,            
            'attributes' => $attributes,
        ]);
    }
    
    public function addText($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'text',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }
    
    
    
    
}

I added my fieldset with this code :

<?php

/**
    * @module     Commun
    * @subpackage Form\Admin
    * @author     Samuel NANGUI <nanguisamuel@gmail.com>
    * @copyright  Copyright (c) 2021 Nslabs
    */

namespace Commun\Form\Modules\Application;

use Commun\Form\Modules\Application\Fieldset\RealisationImpactFieldset;


use Commun\Form\CommunForm;

class RealisationImpactForm extends CommunForm 
{
    
    
    public function init() { 
        parent::init();                 
        $this->setName('RealisationImpactForm');         
        $this->addFieldset(RealisationImpactFieldset::class,['use_as_base_fieldset' => true,'params' => $this->getOption('params')]);
        $this->addSubmitButton('next', 'Poursuivre', 'next', 'btn btn-vert w-100');        
        $this->addSubmitButton('previous', 'Retour', 'previous', 'btn btn-rouge w-100');        
    }  
  
}

here is my addFieldset function

public function addFieldset($fieldset,$options=[]){        
        $this->add([
            'type' => $fieldset,
            'options' => $options,            
        ]);               
    }

and when I do a var_dump I get the option like this :

But I did not get anything in my fielddet.

Here is my factory

<?php

/**
    * @module     Commun
    * @subpackage Form
    * @author     Samuel NANGUI <nanguisamuel@gmail.com>
    * @copyright  Copyright (c) 2020 Nslabs
    */

namespace Commun\Factory\Form\Fieldset;


use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Commun\Form\Modules\Application\Fieldset\RealisationImpactFieldset;

class RealisationImpactFieldsetFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {                  
        $mappers = ['supervision' => $container->get('TSUPERVISION')];          
        return new RealisationImpactFieldset($mappers);
        
    }
}

Ans here is how I call my form in my controller :
$realisationImpactForm = $this->formManager->get(RealisationImpactForm::class,['idProjet' => $id,'idSupervision' => 1]);

Sorry for the late response!

Maybe I missed something, but where are the options accessed in your fieldset?

Also sorry for my late response. I was positive to Coronavirus and very sick.

Here is my fieldset :

<?php

/**
    * @module     Commun
    * @subpackage Form\Admin
    * @author     Samuel NANGUI <nanguisamuel@gmail.com>
    * @copyright  Copyright (c) 2020 Nslabs
    */

namespace Commun\Form\Modules\Application\Fieldset;

use Commun\Model\Entity\Supervision;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Hydrator\ReflectionHydrator;

use Commun\Form\CommunFormFieldset;


class RealisationImpactFieldset extends CommunFormFieldset implements InputFilterProviderInterface
{
        
    
    private $mapper;     
        
    public function __construct($mappers=[],$options=[])
    {              
        $this->mapper = $mappers;                       
        parent::__construct($this->mapper,'RealisationImpactForm',$options);          
        $this->setHydrator(new ReflectionHydrator());
        $this->setObject(new Supervision());
        $this->setLabel('Realisation Impact');          
    }
    
    

    public function init() { 
        
        //$effets = $this->mapper['supervision']->getRapportEffetByProjetForSuivi($this->idProjet,$this->idSupervision);
        //var_dump($this->getOption('params'));
        
        /*$this->addText('libelle','Intitulé de l\'activité','libelle',['class' => 'form-control champ-requis']);
        $options = $this->mapper['indicateur']->getOptions('idRefIndicateur','libelle','Aucune valeur choisie',null,['libelle']);           
        $this->addSelect('idRefIndicateur','Indicateur de performance',$options,['class' => 'form-control']);
        $this->addText('valeurReference','Valeur de référence','valeurReference',['class' => 'form-control champ_decimal']);
        $this->addText('valeurCible','Valeur cible','valeurCible',['class' => 'form-control champ_decimal']);
        $this->addTextarea('moyenVerification', 'Moyen de vérification', 'moyenVerification', ['class' => 'form-control','rows' => 3]); 
        $this->addTextarea('risqueMesureAttenuation', 'Risques et mesures d\'atténuation', 'risqueMesureAttenuation', ['class' => 'form-control','rows' => 3]);  */        
    }
    
        
    /**
     * @return array
     */
    public function getInputFilterSpecification()
    {
        return [
            
        ];
    }
}

and My CommunFormFieldset here :

<?php

/**
    * @module     Commun
    * @subpackage Form
    * @author     Samuel NANGUI <nanguisamuel@gmail.com>
    * @copyright  Copyright (c) 2021 Nslabs
    */

namespace Commun\Form;

use Laminas\Form\Element\Select;
use Laminas\Form\Fieldset;
use Laminas\Form\Element\Checkbox;
use Laminas\Form\Element\MultiCheckbox;
use Laminas\Form\Element\Button;
use Laminas\Form\Element\Hidden;


class CommunFormFieldset extends Fieldset
{        
 
    /**
     * Shortcut for adding an input type text element
     * @param string $name name of the item
     * @param string $label  label of the item
     * @param string $id unique HTML id of the item
     * @param array $attributes array of attributes to apply to the item     
     */
        
    public $additionnalParams;
    private $mapper;
    
    public function __construct($mapper=[],$name=null,$options = []) {    
        //$this->additionnalParams = $options;
        $this->mapper = $mapper;            
        parent::__construct($name, $options);          
    }
    
    
    public function init(){        
        parent::init();
    }
        
    /**
     * Shortcut for adding an input type text element
     * @param string $name name of the item
     * @param string $label  label of the item
     * @param string $id unique HTML id of the item
     * @param array $attributes array of attributes to apply to the item  
     * @param string $labelClass label class(espacially for required item)   
     */
    
    public function addHiddenElement($name,$attributes=[]){
        $this->add([
            'name' => $name,
            'type' => Hidden::class,            
            'attributes' => $attributes,
        ]);
    }
    
    public function addText($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'text',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }
    
    
    /**
     * Shortcut for adding an input type text element
     * @param string $name name of the item
     * @param string $label  label of the item
     * @param string $id unique HTML id of the item
     * @param array $attributes array of attributes to apply to the item  
     * @param string $labelClass label class(espacially for required item)   
     */
    
    public function addFile($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'file',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],            
            'attributes' => $attributes,
        ]);
    }
    
    public function addTextarea($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'textarea',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],                
            ],
            'attributes' => $attributes,
        ]);
    }
    
    /**
     * Shortcut for adding a select list type element
     * @param string $name name of the select item
     * @param string $label  label of the select item
     * @param array $valueOptions array values to populate the Select with
     * @param array $attributes array of attributes to apply to the Select item     
     * @param string $labelClass label class(espacially for required item)
     */
    
    public function addSelect($name,$label,$valueOptions=[],$attributes=[],$labelClass=''){ 
        $this->add([            
            'name' => $name,
            'type' => Select::class,            
            'options' => [
                'label' => $label,
                'value_options' => $valueOptions,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }    
    
    public function addSelectFromTable($name,$label,$type,$attributes=[],$labelClass=''){ 
        $this->add([            
            'name' => $name,              
            'type' => get_class($type) ,            
            'options' => [
                'label' => $label,  
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            //'label_attributes' => ['class'  => $labelClass],
            'attributes' => $attributes,
        ]);        
    }
    
    /**
     * Shortcut for adding a select list type element
     * @param string $name name of the select item
     * @param string $label  label of the select item
     * @param string $id id of the select item
     * @param string $checkedValue value of checked item.    
     * @param string $unCheckedValue value of unchecked item.    
     * @param array $attributes attribute array.    
     * @param string $labelClass label class(espacially for required item)   
     */
    
    public function addCheckbox($name,$label,$id='',$checkedValue='',$unCheckedValue='',$attributes=[],$labelClass=''){ 
        $this->setLabelAttributes(['class' => $labelClass]);
        $this->add([
            'name' => $name,
            'type' => Checkbox::class,
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'use_hidden_element' => true,
                'checked_value' => $checkedValue,
                'unchecked_value' => $unCheckedValue,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }
    
    
    public function addMultiCheckbox($name,$label,$id='',$valueOptions=[],$attributes=[],$labelClass=''){
        $this->add([
            'name' => $name,
            'type' => MultiCheckbox::class,
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'value_options' => $valueOptions,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }
    
    public function addButton($name,$label,$attributes=[]){
        $this->add([
            'name' => $name,
            'type' => Button::class,              
            'options' => [
                'label' => $label,                
            ],
            'attributes' => $attributes,
        ]);
    }
        
    
    
    /**
     * Shortcut for adding a collection list type element
     * @param string $name name of the select item
     * @param string $label  label of the select item
     * @param string $targetElement name of the target fieldset
     * @param boolean $isObject indicate if the variable is an instance of a class or just a string     
     * @param int $count number of visible row
     * @param boolean $shouldCreateTemplate indicate if the html markup must be created
     * @param boolean $allowAdd indicate if new item can to addeds
     */
    
    
    private function getStringFromElement($element){
        if(gettype($element)==='object'){
            return get_class($element);
        }elseif(gettype($element)==='string'){
            return $element;
        }else{
            throw new \Exception('This type cannot be used with collection element');
        }
    }
    
    public function addCollection($name,$label, $targetElement,$count=2,$attributes=[],$templatePlaceholder='__index__',$shouldCreateTemplate=true,$allowAdd=true){         
        $this->add([
            'type' => \Laminas\Form\Element\Collection::class,
            'name' => $name,
            'options' => [
                'label' => $label,
                'count' => $count,
                'should_create_template' => $shouldCreateTemplate,
                'template_placeholder' => $templatePlaceholder,
                'allow_add' => $allowAdd,
                'target_element' => [
                    'type' =>  $this->getStringFromElement($targetElement),                                                         
                ],                 
            ],
            'attributes' => $attributes,
                /*'attributes' => [
                    'class'              => 'fieldset-collection',
                    'data-fieldset-name' => _('City'),
                ],*/
        ]);
    }
    
}