I have two fieldsets in my form. I can hydrate the fieldsets by using setUseAsBaseFieldset(true)
on the fieldset, so I can see the existing data in the form. When I post the form and use getData()
I am only getting the data for one fieldset.
I suspect this is linked to how I have added the fieldset and my need to use setUseAsBaseFieldset(true)
to hydrate them.
My system has three types of accounts - customer and two others. All of them have a basic username, password, role fieldset named customer
.
The way my code is structured: I have an AccountForm which loads the customer fieldset, and my controller then adds the editor fieldset.
//AccountForm.php
public function __construct($config = array()) {
parent::__construct($name = null);
parent::setAttribute('method', 'post');
parent::setAttribute('action', $config['action']);
$this->setHydrator( new ArraySerializable () );
$this->add(new CustomerFieldset(array('adapter' => $config['adapter'])));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'required' => 'required',
'value' => 'Submit',
'class' => 'btn btn-primary',
)
));
}
//CustomerFieldset.php
public function __construct($config) {
parent::__construct('user');
$this->adapter = $config['adapter'];
$this->setObject(new User())
->setHydrator( new ArraySerializable (false));
$this->setUseAsBaseFieldset(true);
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'hidden',
),
));
$this->add(array(
'name' => 'email',
'type' => 'email',
'attributes' => array(
'id' => 'email',
'required' => 'required',
'class' => 'form-control',
),
'options' => array(
'label' => 'Email: ',
),
));
$this->add(array(
'name' => 'firstname',
'type' => 'text',
'attributes' => array(
'id' => 'firstname',
'required' => 'required',
'class' => 'form-control',
),
'options' => array(
'label' => 'First Name: ',
),
));
$this->add(array(
'name' => 'lastname',
'type' => 'text',
'attributes' => array(
'id' => 'lastname',
'required' => 'required',
'class' => 'form-control',
),
'options' => array(
'label' => 'Last Name: ',
),
));
$this->add(array(
'name' => 'role_id',
'type' => 'select',
'attributes' => array(
'id' => 'role',
'required' => 'required',
'class' => 'form-control',
),
'options' => array(
'label' => 'Role: ',
'empty_option' => 'Please select role',
'value_options' => $this->getDbValues('acl_roles'),
),
));
$this->add(array(
'name' => 'password',
'type' => 'password',
'attributes' => array(
'id' => 'password',
'class' => 'form-control',
),
'options' => array(
'label' => 'Password (leave blank to not change): ',
),
));
$this->add(array(
'name' => 'confirm-password',
'type' => 'Password',
'attributes' => array(
'id' => 'confirm-password',
'class' => 'form-control',
),
'options' => array(
'label' => 'Confirm Password: ',
),
));
}
//EditorFieldset.php
public function __construct() {
parent::__construct('editor');
$this->setObject(new Editor())
->setHydrator( new ArraySerializable (false));
$this->add(array(
'name' => 'id',
'type' => 'hidden',
'attributes' => array(
'required' => true,
),
));
$this->add(array(
'name' => 'additional',
'type' => 'text',
'attributes' => array(
'required' => true,
'class' => 'form-control',
'id' => 'additional',
),
'options' => array(
'label' => 'Additional Details: ',
),
));
//... more elements
}
//controller
//$form already has customer fieldset. Add editor fieldset.
$form = $this->getForm();
$fieldset = new EditorFieldset();
$fieldset->setUseAsBaseFieldset(true); //set so I can bind to this fieldset
$form->add($fieldset);
/** @var $editor = row object */
$form->bind($editor);
$user = $form->get('user')->setUseAsBaseFieldset(true); //set so later I can bind to this fieldset
$form->remove('user'); //remove fieldset and re-add it with above param set
$form->add($user, array('priority' => 100)); // 100 - high priority - appear at top of form.
$userTable = $this->getServiceLocator()->get('Application\Model\CustomerTable');
$form->bind($userTable->fetchRowById($id));
$request = $this->getRequest();
if($request->isPost()) {
$form->getInputFilterSpecification();
$data = $request->getPost();
$form->setData($data);
if ($form->isValid()) {
$validatedData = $form->getData();
var_dump($validatedData); //debug
}
}
//...view model and other stuff
When I remove the setUseAsBaseFieldset(true)
from the fieldsets, then I get all the values when I use getData()
, however the form does not populate the fields.
Based on my last comment, I have wrapped my setUseAsBaseFieldset(true)
statements in glorious if
statements:
if(!$this->getRequest()->isPost()) {
$fieldset->setUseAsBaseFieldset(true);
}
I do not feel this is the correct solution. More of a hacky fix to a problem I've created.