Issue: multiple fieldsets in form are not populated/hydrated when using $form->bind($object). How do you populate 2 different fieldsets in a form vai 2 different entity objects? I have 2 fieldsets: FieldsetA, FieldsetB
A form RegisterFrom calls these in its init() method
class RegisterForm extends Form
{
public function init(){
$this->add(array(
'name' => 'service_provider_fieldset',
'type' => ServiceProviderFieldset::class, // this is one model/entity
));
$this->add(array(
'name' => 'location_fieldset',
'type' => LocationFieldset::class, // this is a separate model/entity
));
}
}
Creating the fieldsets: (note commented out attempts at hydration)
class ServiceProviderFieldset extends Fieldset
{
public function init(){
//parent::__construct($name);
/*
$this
->setHydrator(new ClassMethodsHydrator(false))
->setObject(new ServiceProvider())
;
*/
/*
$this
->setHydrator(new ReflectionHydrator(false))
->setObject(new ServiceProvider())
;
*/
$this->add(array(
'type'=>'Hidden',
'name'=>'id',
'options'=>array(
'label' => 'Service Provider Id'
),
'attributes'=>array(
'id'=>'providerId'
)
));
}
}
Controller:
$provider = $this->findServiceProviderById($providerId); // this is set from DB call and correctly creates a Provider() object with populated values.
$location = $this->findServiceProviderLocationById($locId);
$form = $formManager->get(RegisterForm::class);
$form->bind($provider);
$form->bin($location);
// $form->get('service_provider_fieldset')->bindValues(...);
View:
$formElement = $form->get('service_provider_fieldset')->get('email');
etc...
The form renders in the view correctly BUT without the populated data.
NOTE: NOT using Doctrine but I retrieve the data from the DB OK. NOTE: IF I set this flag 'use_as_base_fieldset' => true, then 1 of the Objects (ServiceProvider) populates, visa-versa if I set the location fields to 'true' then that populates. I've been searching for a couple of hours, trial and error with no success and I'm hoping it's just my fatigue which has missed a simple setup/config step to get this to work.
Summary: How do you populate 2 or more Fieldsets with 2 or more entities within a form? Bind(), fieldset->bindValues()?,
Tried:
$form->get('service_provider_fieldset')->allowObjectBinding(true);
$form->get('service_provider_fieldset')->allowedObjectBindingClass(\Provider\Form\ServiceProviderFieldset::class);
These are some links that are close but still cannot populate both field sets via separate entities. ZF2 Form Hydration with multiple objects and fieldsets https://framework.zend.com/manual/2.4/en/modules/zend.form.collections.html hydrating multiple objects from fieldsets ZF2
The collections (product/brand/category) example implies a 'single' collection using the 'use_as_base_fieldset' => true, is used to bind()...?
On your webpage, check the form's elements names that relate to your fieldsets. They should be something like this:
yourFieldsetName[yourElementName]
. If you just seeyourElementName
, that most likely means that forgot toprepare()
your form in the view script.This is exactly what happened to me, and after I
prepare()
ed the form, all the objects got hydrated without a problem.UPDATE = answer to comment's questions: Not resolved as such. Is this bad design? Note: I am using prepare() on in the view.
If everything works fine, your 2 objects should hydrate.
use_as_base_fieldset
flag is used for basically saying, 'hey that's me (the fieldset) you should only hydrate object with data/extract data from object'. So what you get with one object being hydrated and the other not, and vice versa is predictable. It's quite difficult to say what's going wrong without looking at your complete code. I'm afraid posting too much will also take time for the answerer's to grasp, and my experience is that such questions are usually left unanswered. What I usually do in situations like yours is that I go step by step in the ZendForm
's andFieldset
s methods used in hydration/extraction. I use\Zend\Debug\Debug::dump($somethingThatYouWantToCheck); die();
. That's not the best method I presume, but it works.If I were you, I would also do the following.
From your post, it's not clear why you use form's
init()
method. Theinit()
method is used when you want, for example, some elements in your form be filled from DB (like<select>
). TheForm
runsinit()
method when some things that aren't available in in the__construct()
method yet, but only after the instance of the form is created (not 100% sure about this, double-check this).Don't worry about good/bad design. Design is a very good thing, but if you have a small or middle system, the design considerations won't affect the performance/complexity of the system. But rather you'll spend really a lot of time doing everything right than just doing it and if it works ok, forgetting about it.
If you don't wanna go with
\Zend\Debug\Debug::dump($somethingThatYouWantToCheck); die();
(that could be quite tedious, I know), create one fieldset and attach to it your desired 2 fieldsets. Then include this fieldset in the form and useuse_as_base_fieldset = true
on this fieldset (of course you'll also need to create object corresponding to this fieldset with 2 nested objects that are attached to your current fieldsets, and attach the object to the fieldset).Hope this helps at least a little.