Search code examples
phpzend-frameworkzend-formzend-framework3zend-form2

How can I change count of a Collection Fieldset in Zend Form when using Annotations?


From https://docs.zendframework.com/zend-form/quick-start/#using-annotations:

Via using Zend\Form\Annotation, I can issue this directive:

/**
 * @ComposedObject({
 *     "target_object":"Namespace\Model\ComposedCollection",
 *         "is_collection":"true",
 *         "options":{"count":2}
 *     }); 
 */
private $property;

What this does is create a collection of ComposedCollection elements, in the above case, of size 2.

It's great when I need a static form with 2 elements, but how do I change it when I want to alter it dynamically? i.e. internally I want to be able to populate the form with 4 or 5 sets of data, with the number being unknown ahead of time.

Using Annotations is static, and not dynamic. Is there any way to do this?

I have tried using

$form->get("element_name")->setOption("count", $numericValue);

but it does not work, because I am guessing by the time I am using it, the form has already been built by the Annotation engine ($annotationBuilder->createForm(MyEntity::class);

Is there a way to rebuild the form?

I have tried $form->prepare()

but it only actually removes my Collection elements instead.

I have also tried $form->init() but it appears to do nothing.

I am in the process of rewriting the form NOT using Annotations, but that's not what I am trying to accomplish, since I am effectively losing my Entity by rewriting it in a programmatic way.


Solution

  • Use Collection::setCount() method.

    $form->get("element_name")->setCount($numericValue);
    

    Also, as an alternative you can define fieldset programmatically. Place @Annotation\Exclude() on the $property and create a Fieldset like so:

        $c = new Element\Collection('collection');
        $c->setOptions([
            'label' => 'Collection',
            'count' => 1    ,
            'should_create_template' => true,
            'allow_add' => true,
            'target_element' => [
                'type' => ComposedCollectionFieldset::class
            ]
        ]);
    

    Where ComposedCollectionFieldset contains the Elements that you need.