12

I use Zend\Form\Factory to create forms in zend framework2

$factory = new Zend\Form\Factory();
$factory->createForm(array(
    'elements' => array(
        array(
            'spec' => array(
                'name' => 'name',
            ),
        ),
    ),
    'input_filter' => array(
        'name' => array(
            'validators' => array(
                // validators for field "name"
            ),
            'filters' => array(
                // filters for field "name"
            ),
        ),
    ),
));

You can see that there are filters and validators for field "name". It works. I have the problem if I use fieldsets:

$factory->createForm(array(
    'fieldsets' => array(
        array(
            'spec' => array(
                'name' => 'common',
                'elements' => array(
                    array(
                        'spec' => array(
                            'name' => 'name',
                        ),
                    ),
                ),
            ),
        ),
    ),   
    'input_filter' => array(
        'name' => array(
            'validators' => array(
                // validators for field "name"
            ),
            'filters' => array(
                // filters for field "name"
            ),
        ),
    ), 
));

In this example input filter doesn`t work. I don't know how to set filters and validators to field "name" in fieldset "common"

This example does not work too:

$factory->createForm(array(
    'fieldsets' => array(
        array(
            'spec' => array(
                'name' => 'common',
                'elements' => array(
                    array(
                        'spec' => array(
                            'name' => 'name',
                        ),
                    ),
                ),
                'input_filter' => array(
                    'name' => array(
                        'validators' => array(
                            // validators for field "name"
                        ),
                        'filters' => array(
                            // filters for field "name"
                        ),
                    ),
                ), 
            ),
        ),
    ),       
));
Ildar
  • 798
  • 2
  • 14
  • 35
  • Define the validators and filter specs inside the relevant fieldset spec, not at on the top-level form spec. – timdev Apr 27 '13 at 03:04
  • I tried to do this, but it doesn`t work too. (updated question) ZF2 2.1.5 – Ildar Apr 27 '13 at 06:46
  • Hmm... I can't test it at the moment, but I suspect you need a `'name'=>'name',` key/value pair inside your main 'name' key. I'll try to check. – timdev Apr 27 '13 at 22:26

3 Answers3

18

You need to specify 'type' key in input filter when you used fieldset.

$factory = new \Zend\Form\Factory();        
$form    = $factory->createForm(array(
    'hydrator'  => 'Zend\Stdlib\Hydrator\ArraySerializable',
    'elements' => array(
        array(
            'spec' => array(
            'name' => 'email1',
            ),
        ),
    ),  
    'fieldsets' => array(
        array(
            'spec' => array(
                'name' => 'common',
                'elements' => array(
                    array(
                        'spec' => array(
                        'name' => 'email2',
                        ),
                    ),
                ),
            ),
        ),
    ),
    'input_filter' => array(                
        'email1' => array(
            'validators' => array(
            // validators for field "name"                        
                new \Zend\Validator\EmailAddress(),
            ),
            'filters' => array(
            // filters for field "name"
                array('name' => 'Zend\Filter\StringTrim'),
            ),
         ),
        'common' => array(
            'email2' => array(
                'validators' => array(
                // validators for field "name"                        
                new \Zend\Validator\EmailAddress(),
                ),
                'filters' => array(
                // filters for field "name"
                array('name' => 'Zend\Filter\StringTrim'),
                ),
            ),
            'type' => 'Zend\InputFilter\InputFilter',
         )          
    ),

));

$form->setData(array('email1'=>'test@gmail.com','common'=>array('email2'=>'invalid-email')));
if(!$form->isValid()){
    print_r($form->getMessages());
}
Malkesh
  • 502
  • 4
  • 12
  • I don't think 'validators' => array( // validators for field "name" new \Zend\Validator\EmailAddress(), ), is working... because validator ask for key value pare of array and gives this error "Invalid validator specification provided; does not include "name" key".. any solution ? – Ruwantha Oct 21 '13 at 05:06
2

If you want to add dynamic validators in the Action (for example validators that are required only when some other fields have a specific value), it is quite a puzzle to apply this when using form collection.

In order to achieve this you should grab the validator chain from the specific element. For each fieldset however, you should first hook in it's own input filter. I would like to share this, because this took me 2 hours to understand ;)

Let's say you have a base form, the base form has a fieldset, and the fieldset has x-elements. The code to add a validator to one of the x-elements requires following chain:

$form->getInputFilter()
     ->get('base-form')
     ->get('fieldset-form')
     ->getInputFilter()
     ->get('element')
     ->getValidatorChain()
     ->addValidator($validator);

The 2 getInputFilter() can give you an headache.

Nykac
  • 129
  • 2
  • 7
1

You have your syntax incorrect, are common and spec supposed to be nested fieldsets or something? Not sure what you are doing there... Try removing the spec part

$factory = new Factory();
$form    = $factory->createForm(array(
'fieldsets' => array(
    array(
        'name' => 'details',
        /**
         * Elements for the "details" form
         */
        'elements' => array(
            array(
                'name' => 'name',
                'type'  => 'Text',
                'options' => array(
                    'label' => 'Full name',
                    ),

            ),
            array(
                'type' => 'Zend\Form\Element\Email',
                'name' => 'email',
                'options' => array(
                    'label' => 'Email address',
                    ),
            ),
        ),
    ),
    array(
        'name' => 'extra',
        'elements' => array(
            array(
                'name' => 'address',
                'type'  => 'Text',
                'options' => array(
                    'label' => 'Address',
                ),
            ),
            array(
                'name' => 'notes',
                'type' => 'Zend\Form\Element\Textarea',
                'options' => array(
                    'label' => 'Notes',
                ),
            ),
        ),
    ),
),
/**
 * Elements on the form itself, not in the fieldsset
 */
'elements' => array(
    array(
        'type' => 'Zend\Form\Element\Captcha',
        'name' => 'captcha',
        'options' => array(
            'captcha' => array(
                'class' => 'Dumb',
            ),
        ),
    ),
    array(
        'type' => 'Zend\Form\Element\Csrf',
        'name' => 'security',
    ),
    array(
        'name' => 'send',
        'type'  => 'Submit',
        'attributes' => array(
            'value' => 'Submit',
        ),
    ),
),
/*/
 * Input Filters Spec here
 */
'input_filter' => array(
    'name' => array(
        'validators' => array(
            // validators for field "name"
        ),
        'filters' => array(
            // filters for field "name"
        ),
    ),
),
));
Andrew
  • 12,617
  • 1
  • 34
  • 48
  • My syntax is correct, I have checked it. Common is just a name of fieldset. "common" index in fielsets array was just for me, for easy access, I already removed "common" index from post. spec is required, without it I get exception "Zend\Form\Fieldset::add: element or fieldset provided is not named, and no name provided in flag". So, your code is incorrect – Ildar Apr 30 '13 at 09:25
  • 1
    My code is incorrect? that's funny it's directly from the docs, spec is not required. – Andrew Apr 30 '13 at 12:53
  • I think this is documentation error. Example really doesn't work. https://github.com/zendframework/zf2/issues/2561 – Ildar Apr 30 '13 at 16:10