Ron
Ron

Reputation: 23466

Zend Framework 2 - Annotation form - Bind doesn't work

I'm using AnnotationForms and I altered my standard edit action from the tutorial to use Annotation and not standard forms.

Everything works except the $form->bind() doesn't fill in the values. The form fields stay empty.

I checked my variable which should be binded and it is set and looks good.

Here's my action:

    $id = (int)$this->getEvent()->getRouteMatch()->getParam('id');
    if (!$id) {
        return $this->redirect()->toRoute('album', array('action'=>'add'));
    }
    $album = $this->getEntityManager()->find('Album\Entity\Album', $id);

    $builder = new AnnotationBuilder();
    $form    = $builder->createForm(new \Album\Entity\Album());
    $form->add(new \MyVendor\Form\MyFieldset());
    $form->setBindOnValidate(false);
    $form->bind($album);

Upvotes: 3

Views: 2227

Answers (2)

Frank
Frank

Reputation: 178

The ClassMethods hydrator does actually work on bind, but the form element names need to match the lower-case-underscore Format (example: object property $moduleDisplayName, ClassMethods and ObjectProperty hydrator expect form element Name module_display_name.

The Zend\Form\Annotation by default produces a form element named moduleDisplayName. Therefore extracting the object to the form does not work.

Solution 1: Add the @Name Annotation to the property for ClassMethods to work.

Example:

/**
* @Form\Name("module_display_name")
protected $moduleDisplayName

Solution 2: Instantiate the ClassMethods hydrator with the optional Parameter underScoreSeperatedKeys set to false (Default is true) or use ClassMethods::setUnderScoreSeperatedKeys(false). Then ClassMethods will behave like any other hydrator.

The ObjectProperty hydrator works only on properties declared public. But naming is the same as with ArraySerializable (i.e. property $moduleDisplayName, form element Name moduleDisplayName).

The Reflection hydrator works on all properties. Naming is the same as with ArraySerializable.

Conclusion: ClassMethods is the one of four hydrators which expects a different form element naming scheme. Not too cool.

Upvotes: 2

Ron
Ron

Reputation: 23466

Alright, this was an easy one!

The trick is to transform your object to an array and use setData() instead of bind.

I found the solution hint here.

You still need bind() for saving the changes. If you leave it out, no error occurs but it won't save it either.

 $album = $this->getEntityManager()->find('Album\Entity\Album', $id);
 ...
 $form->bind($album);
 $form->setData($album->getArrayCopy());

Upvotes: 2

Related Questions