ZF2 - Control/customise individual radio/checkboxes - php

I'm attempting to add data- values on radio buttons within ZF2. Is it possible to control each of the inputs specified with value_options?
A typical radio button added to a form:
$this->add(array(
'type' => 'radio',
'name' => 'duration',
'options' => array(
'value_options' => array(
'daily' => 'Daily',
'weekly' => 'Weekly',
'monthly' => 'Monthly',
),
),
));
Ultimately, I would like something like the following, so I can specify individual parameters/options for each radio item:
$this->add(array(
'type' => 'radio',
'name' => 'duration',
'options' => array(
'value_options' => array(
array(
'attributes' => array(
'value' => 'daily',
'data-item' => 'apple'
),
'options' => array(
'label' => 'Daily'
)
),
array(
'attributes' => array(
'value' => 'weekly',
'data-item' => 'orange'
),
'options' => array(
'label' => 'Weekly'
)
),
array(
'attributes' => array(
'value' => 'monthly',
'data-item' => 'pear'
),
'options' => array(
'label' => 'Monthly'
)
),
),
),
));
My reason for wanting the above, is that I want to use JavaScript to change something upon selecting a radio button, so it needs to hold data attributes.
Is anything like this possible yet?

It can be done by providing an array (or an object which implements ArrayAccess) instead of a single value (almost as you wrote in your example).
$this->add(array(
'type' => 'radio',
'name' => 'duration',
'options' => array(
'value_options' => array(
'daily' => array(
'label' => 'Daily',
'value' => 'daily',
'attributes' => array(
'data-item' => 'apple',
),
),
'weekly' => array(
'label' => 'Weekly',
'value' => 'weekly',
'attributes' => array(
'data-item' => 'orange',
),
),
'monthly' => array(
'label' => 'Monthly',
'value' => 'monthly',
'attributes' => array(
'data-item' => 'pear',
),
),
),
),
));
https://github.com/zendframework/zf2/blob/master/library/Zend/Form/View/Helper/FormMultiCheckbox.php#L177
This should work on radios, multi-checkboxes & selects too.

Related

Set NotEmpty validator error message

I am trying to set a custom error message with ZF2 form and the NotEmpty validaor.
In my form I have the following radio element.
$this->add(array(
'name' => 'paymentMethod',
'type' => 'Radio',
'options' => array(
'label' => _('Payment Methods:'),
'value_options' => $paymentMethods,
'disable_inarray_validator' => TRUE,
),
));
and in my input filter I have
$inputFilter->add(array(
'name' => 'paymentMethod',
'required' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'break_chain_on_failure' => true,
'options' => array(
'messages' => array(
NotEmpty::IS_EMPTY => _("You must select the payment method"),
),
),
),
array(
'name' => 'InArray',
'options' => array(
'haystacK' => $this->getPaymentMethods(),
'messages' => array(
InArray::NOT_IN_ARRAY => _("This payment method does not exist"),
),
),
),
),
));
As can be seen in my input filter I have set a custom message for my NotEmpty validator. The problem I am having is that the form outputs the default error message 'Value is required and can't be empty' and not my custom one.
I assume that this has something to do with the 'required' => TRUE automatically setting a NotEmpty validator but I don't know how to disable this.
I have other text elements with this validator and they display the custom error message fine, this radio element just does not. I also have a multicheckbox element that has the same problem.
Does anyone know as to why this is happening?
Many thanks in advance.
EDIT
I am now having the same problem with another element, in this case its DoctrineModule\Form\Element\ObjectMultiCheckbox.
The element is defined
$this->add(array(
'name' => 'categories',
'type' => 'Admin\DoctrineModule\Form\Element\ObjectMultiCheckbox',
'options' => array(
'label' => _('Categories:'),
'label_attributes' => array('class' => 'required'),
'object_manager' => $this->getEntityManager(),
'target_class' => 'Application\Entity\Categories',
'property' => 'category',
'is_method' => true,
'find_method' => array(
'name' => 'FindAll',
),
'disable_inarray_validator' => TRUE,
),
));
and in my getInputFilterSpecification() method I have
...
'categories' =>
array(
'required' => TRUE,
'allow_empty' => TRUE,
'continue_if_empty' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'break_chain_on_failure' => true,
'options' => array(
'messages' => array(
NotEmpty::IS_EMPTY => _("You must select the items categories"),
),
),
),
array(
'name' => 'Freedom\Zend\Validator\Doctrine\Db\DoctrineRecordExists',
'options' => array(
'entityManager' => $this->getEntityManager(),
'entity' => 'Application\Entity\Categories',
'identifier' => 'catagoryId',
'messages' => array(
DoctrineRecordExists::ERROR_NO_RECORD_FOUND => _("This category does not exist"),
),
),
),
),
)
...
As you can see I have tried the 'allow_empty' and 'continue_if_empty' options but with no luck. I have also tried 'required' => FALSE, but the element simply passes validation.
The default message shows when NotEmpty validation fails.
Modify your input filter change the 'required' => TRUE, option to 'required' => false
$inputFilter->add(array(
'name' => 'paymentMethod',
'required' => false,
'filters' => array(
array('name' => 'Int'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'break_chain_on_failure' => true,
'options' => array(
'messages' => array(
NotEmpty::IS_EMPTY => _("You must select the payment method"),
),
),
),
array(
'name' => 'InArray',
'options' => array(
'haystacK' => $this->getPaymentMethods(),
'messages' => array(
InArray::NOT_IN_ARRAY => _("This payment method does not exist"),
),
),
),
),
));
I made some changes in your code but i did not test. Try and let me know if it worked. Good luck
$inputFilter->add(array(
'name' => 'paymentMethod',
'required' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
NotEmpty::IS_EMPTY => "You must select the payment method",
),
),
'break_chain_on_failure' => true
),
array(
'name' => 'InArray',
'options' => array(
'haystacK' => $this->getPaymentMethods(),
'messages' => array(
InArray::NOT_IN_ARRAY => _("This payment method does not exist"),
),
),
),
),
));
I have found the solution to my problem.
i changed the 'required' => TRUE, option to 'allow_empty' => TRUE, and now my error message is showing correctly.
$inputFilter->add(array(
'name' => 'paymentMethod',
'allow_empty' => TRUE,
'filters' => array(
array('name' => 'Int'),
),
'validators' => array(
array(
'name' => 'NotEmpty',
'options' => array(
'messages' => array(
NotEmpty::IS_EMPTY => _("You must select the payment method"),
),
),
'break_chain_on_failure' => true,
),
array(
'name' => 'InArray',
'options' => array(
'haystacK' => $this->getPaymentMethods(),
'messages' => array(
InArray::NOT_IN_ARRAY => _("This payment method does not exist"),
),
),
),
),
));
I assume not setting the required option to true stops the auto creation of a NotEmpty validator.

Zend 2 Form Select multiple : How to preselect values

I have the following form element configured and i don't know why the values are not preselected.
$this->add(array(
'name' => 'item_ids',
'type' => 'Select',
'attributes' => array(
'id' => 'item_ids',
'class' => 'form-control',
'multiple' => 'multiple',
'value' => array('1','2'),
),
'options' => array(
'label' => 'Items',
'label_attributes' => array(
'class' => 'col-sm-2 control-label',
),
'value_options' => array(
'1' =>'Item 1',
'2' =>'Item 2',
'3' =>'Item 3'
),
)
));
I want that the "Item 1" and "Item 2" are preselected.
I hope someone can help me with my problem.
#### Update ####
Found something like that in the documentation, i will give it a try :
'value_options' => array(
array(
'value' => '1',
'label' => 'Orange',
'selected' => true,
),
array(
'value' => '2',
'label' => 'Lemon',
),
),
you can set form values like :
$form->getElement('selector')->setValue('val');
or
$form->setDefaults(array(
'selector' => 'val'
));
As I mentioned in the Update of my first post, I found something that seemed to be the right way.
I tested it and this is the solution :
$this->add(array(
'name' => 'item_ids',
'type' => 'Select',
'attributes' => array(
'id' => 'item_ids',
'class' => 'form-control',
'multiple' => 'multiple',
),
'options' => array(
'label' => 'Items',
'label_attributes' => array(
'class' => 'col-sm-2 control-label',
),
'value_options' => array(
array(
'value' => '1',
'label' => 'Item 1',
'selected' => true,
),
array(
'value' => '2',
'label' => 'Item 2',
'selected' => true,
),
array(
'value' => '3',
'label' => 'Item 3',
),
),
)
));

Create Textarea input box in Zend 2 Form

I'm trying to set a textarea in a Zend Form but it always creates an input type text box.
I read some code using the Zend\Form\Element\Textarea but still no luck
This is how I am doing it in my ProjectForm.php:
$this->add(array(
'name' => 'summary',
'type' => 'Zend\Form\Element\Textarea',
'options' => array(
'label' => 'Resumen',
),
));
And in Project.php I have this
$inputFilter->add($factory->createInput(array(
'name' => 'summary',
'required' => true,
'filters' => array(
array('name' => 'StripTags'),
array('name' => 'StringTrim'),
),
'validators' => array(
array(
'name' => 'StringLength',
'options' => array(
'encoding' => 'UTF-8',
'min' => 1,
'max' => 500,
),
),
),
)));
Thanks
Nevermind, I was calling echo $this->formInput instead of echo $this->formTextarea viewHelper.
You have to mention the type in attributes:
$this->add(array(
'name' => 'summary',
'attributes' => array(
'id' => 'summary'
'type' => 'textarea',
'class' => '',
),
'options' => array(
'label' => 'Resumen',
),
)
);

loop options into array

I have an array that has a value with multiple options that is broken down into it's own array. One of those values I want to populate with a loop. Is this possible with the ; in the forloop I would think it would break. What is the best way to accomplish this request?
array(
'name' => __('Ensemble List', 'januas'),
'type' => 'checkbox',
'options' => array(
for ($x=0; $x<=10; $x++){
array('name' => __($x , 'title'), 'value' => $x)
}
)
),
Here is the complete array outside of what I posted:
$meta_boxes[] = array(
'id' => 'januas_speakers',
'title' => __('Ensemble', 'januas'),
'pages' => array('ja-event'),
'context' => 'normal',
'priority' => 'high',
'show_names' => true,
'fields' => array(
array(
'name' => __('Visible', 'januas'),
'desc' => __('Select Yes to show the box in the event page, No to hide it.', 'januas'),
'id' => 'januas_speakers_visible',
'type' => 'select',
'options' => array(
array('name' => __('Yes', 'januas'), 'value' => 'y'),
array('name' => __('No', 'januas'), 'value' => 'n'),
)
),
array(
'name' => __('Position', 'januas'),
'desc' => __('Select the preferred position for the box.', 'januas'),
'id' => 'januas_speakers_position',
'type' => 'select',
'options' => array(
array('name' => __('Main', 'januas'), 'value' => 'main'),
array('name' => __('Sidebar', 'januas'), 'value' => 'sidebar'),
)
),
array(
'name' => __('Order', 'januas'),
'desc' => __('Insert the box order (ex: 1).', 'januas'),
'id' => 'januas_speakers_order',
'std' => 1,
'type' => 'text_small'
),
array(
'name' => __('Show Title', 'januas'),
'desc' => __('Select Yes to show the box title, No to hide it.', 'januas'),
'id' => 'januas_speakers_showtitle',
'type' => 'select',
'options' => array(
array('name' => __('Yes', 'januas'), 'value' => 'y'),
array('name' => __('No', 'januas'), 'value' => 'n'),
)
),
array(
'name' => __('Show in Top menu', 'januas'),
'desc' => __('Select Yes to show the menu item in the event page top menu, No to hide it.', 'januas'),
'id' => 'januas_speakers_showinmenu',
'type' => 'select',
'options' => array(
array('name' => __('Yes', 'januas'), 'value' => 'y'),
array('name' => __('No', 'januas'), 'value' => 'n'),
)
),
array(
'name' => '',
'desc' => '',
'id' => 'januas_images_gallery',
'type' => 'image_gallery'
),
array(
'name' => __('Ensemble List', 'januas'),
'desc' => 'Select the ensemble memebers for this event.',
'id' => 'januas_speakers_completelist',
'type' => 'checkbox',
'options' => array_map(function ($x) {
return array(
'name' => __($x, 'januas'),
'value' => $x,
);
}, range(0,11))
),
array(
'name' => __('Display order', 'januas'),
'desc' => '',
'id' => 'januas_speakers_speakersorder',
'type' => 'event_speakers'
),
array(
'name' => '',
'desc' => '',
'id' => 'januas_speakers_backtotop',
'type' => 'backtotop'
)
),
);
You could use array_map:
array(
'name' => __('Ensemble List', 'januas'),
'type' => 'checkbox',
'options' => array_map(function ($x) {
return array(
'name' => __($x, 'title'),
'value' => $x,
);
}, range(0,11))
),
You should use array_push
$a = array(
'name' => __('Ensemble List', 'januas'),
'type' => 'checkbox',
'options' => array()
);
for ($x=0; $x<=10; $x++){
array_push( $a['options'], array('name' => __($x , 'title'), 'value' => $x) );
}
print_r($a);
Do you need to run the loop inside of options? How about this approach.
$foo = array();
for ($x=0;$x<10;$x++)
$foo[] = $x;
$bar = array(
'name' => 'hello',
'options' => $foo
);
print_r($bar);
https://eval.in/54925

How to set filters and validators in ZF2 fieldsets using Zend\Form\Factory?

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"
),
),
),
),
),
),
));
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());
}
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.
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"
),
),
),
));

Categories