How can I generate nested fieldsets using Zend Form 2?

405 Views Asked by At

enter image description here

Hi, there! I wanna create a form like the above image through the zend framework 2. The input fields will be like:

1. dependent_features[0], 2. dependent_features[1] etc

and their corresponding independent features like:

1. independent_features[0][], 2. independent_features[1][] etc.

Now, how can I generate this kind of form with the collection input fields as well as its validations?

1

There are 1 best solutions below

4
On

See https://docs.zendframework.com/zend-form/collections/#creating-fieldsets

First, let Zend Form define your HTML. (Not the other way around).

For example, for your case you can define 3 classes: ParentContainer, which contains Collection of DependentFeature Fieldsets. Each DependentFeature Fieldset contains Select element, and a Collection of IndependentFeature Fieldsets. Each IndependentFeature Fielset contains a single Select element.

Resulting HTML came out like this:

dependentFeatures[0][dependentFeature]
dependentFeatures[0][independentFeatures][0][independentFeature]
dependentFeatures[0][independentFeatures][1][independentFeature]
dependentFeatures[0][independentFeatures][2][independentFeature]

dependentFeatures[1][dependentFeature]
dependentFeatures[1][independentFeatures][0][independentFeature]
dependentFeatures[1][independentFeatures][1][independentFeature]
dependentFeatures[1][independentFeatures][2][independentFeature]

In other words, define the Collection of elements, nest them, and let Zend do the HTML work for you.

Using Zend Form Annotations you can do something like this:

/**
 * @Annotation\Name("parentContainer")
 * @Annotation\Hydrator({"type":"Zend\Hydrator\ClassMethods", "options": {"underscoreSeparatedKeys": false}})
 */
class ParentContainer
{

    /**
     * @Annotation\ComposedObject({
     * "target_object":"DependentFeature",
     * "is_collection":"true",
     * "options":{"count":2}
     * });
     *
     * @var DependentFeature[]
     */
    private $dependentFeatures;
}

/**
 * @Annotation\Name("dependentFeature")
 * @Annotation\Hydrator({"type":"Zend\Hydrator\ClassMethods", "options": {"underscoreSeparatedKeys": false}})
 * @Annotation\Instance("DependentFeature")
 * @Annotation\Type("Zend\Form\Fieldset")
 */
class DependentFeature
{

    /**
     * @Annotation\Type("Zend\Form\Element\Select")
     * @Annotation\Options({"label":"Dependent Feature:"})
     */
    private $dependentFeature;

    /**
     *
     * @Annotation\ComposedObject({
     * "target_object":"IndependentFeature",
     * "is_collection":"true",
     * "options":{"count":3}
     * });
     *
     * @var IndependentFeature[]
     */
    private $independentFeatures;
}

/**
 * *
 * @Annotation\Name("independentFeature")
 * @Annotation\Hydrator({"type":"Zend\Hydrator\ClassMethods", "options": {"underscoreSeparatedKeys": false}})
 * @Annotation\Instance("IndependentFeature")
 * @Annotation\Type("Zend\Form\Fieldset")
 */
class IndependentFeature
{

    /**
     * @Annotation\Type("Zend\Form\Element\Number")
     * @Annotation\Options({"label":"Independent Feature:"})
     */
    private $independentFeature;
}

Create the form like so:

$form = (new AnnotationBuilder())->createForm(ParentContainer::class);

If you are not using Annotations, you can still build it as I mentioned above -> by nesting Collection of Fieldsets into you Collection of Fieldsets.

How exactly you name and nest your elements depends on your exact domain requirements.