How to validate a checkbox in ZF2 - zend-framework

I've read numerous workarounds for Zend Framework's lack of default checkbox validation.
I have recently started using ZF2 and the documentation is a bit lacking out there.
Can someone please demonstrate how I can validate a checkbox to ensure it was ticked, using the Zend Form and Validation mechanism? I'm using the array configuration for my Forms (using the default set-up found in the example app on the ZF website).

Try this
Form element :
$this->add(array(
'type' => 'Zend\Form\Element\Checkbox',
'name' => 'agreeterms',
'options' => array(
'label' => 'I agree to all terms and conditions',
'use_hidden_element' => true,
'checked_value' => 1,
'unchecked_value' => 'no'
),
));
In filters, add digit validation
use Zend\Validator\Digits; // at top
$inputFilter->add($factory->createInput(array(
'name' => 'agreeterms',
'validators' => array(
array(
'name' => 'Digits',
'break_chain_on_failure' => true,
'options' => array(
'messages' => array(
Digits::NOT_DIGITS => 'You must agree to the terms of use.',
),
),
),
),
)));

You could also just drop the hidden form field (which I find a bit weird from a purist HTML point of view) from the options instead of setting its value to 'no' like this:
$this->add(array(
'type' => 'Zend\Form\Element\Checkbox',
'name' => 'agreeterms',
'options' => array(
'label' => 'I agree to all terms and conditions',
'use_hidden_element' => false
),
));

I had the same problem and did something similar to Optimus Crew's suggestion but used the Identical Validator.
If you don't set the checked_value option of the checkbox and leave it as the default it should pass in a '1' when the data is POSTed. You can set it if you require, but make sure you're checking for the same value in the token option of the validator.
$this->filter->add(array(
'name' => 'agreeterms',
'validators' => array(
array(
'name' => 'Identical',
'options' => array(
'token' => '1',
'messages' => array(
Identical::NOT_SAME => 'You must agree to the terms of use.',
),
),
),
),
));
This won't work if you use the option 'use_hidden_element' => false for the checkbox for the form. If you do this, you'll end up displaying the default NotEmpty message Value is required and can't be empty

This isn't directly related to the question, but here's some zf2 checkbox tips if you're looking to store a user's response in the database...
DO use '1' and '0' strings, don't bother trying to get anything else to work. Plus, you can use those values directly as SQL values for a bit/boolean column.
DO use hidden elements. If you don't, no value will get posted with the form and no one wants that.
DO NOT try to filter the value to a boolean. For some reason, when the boolean value comes out to be false, the form doesn't validate despite having 'required' => false;
Example element creation in form:
$this->add([
'name' => 'cellPhoneHasWhatsApp',
'type' => 'Checkbox',
'options' => [
'label' => 'Cell phone has WhatsApp?',
'checked_value' => '1',
'unchecked_value' => '0',
'use_hidden_element' => true,
],
]);
Example input filter spec:
[
'cellPhoneHasWhatsApp' => [
'required' => false,
],
]
And here's an example if you want to hide some other form fields using bootstrap:
$this->add([
'name' => 'automaticTitle',
'type' => 'Checkbox',
'options' => [
'label' => 'Automatically generate title',
'checked_value' => '1',
'unchecked_value' => '0',
'use_hidden_element' => true,
],
'attributes' => [
'data-toggle' => 'collapse',
'data-target' => '#titleGroup',
'aria-expanded' => 'false',
'aria-controls' => 'titleGroup'
],
]);
I'm a ZF2 fan, but at the end of the day, you just have to find out what works with it and what doesn't (especially with Forms). Hope this helps somebody!

Very old question, but figured it might still be used/referenced by people, like me, still using Zend Framework 2. (Using ZF 2.5.3 in my case)
Jeff's answer above helped me out getting the right config here for what I'm using. In my use case I require the Checkbox, though leaving it empty will count as a 'false' value, which is allowed. His answer helped me allow the false values, especially his:
DO NOT try to filter the value to a boolean. For some reason, when the boolean value comes out to be false
The use case is to enable/disable certain entities, such as Countries or Languages so they won't show up in a getEnabled[...]() Repository function.
Form element
$this->add([
'name' => 'enabled',
'required' => true,
'type' => Checkbox::class,
'options' => [
'label' => _('Enabled'),
'label_attributes' => [
'class' => '',
],
'use_hidden_element' => true,
'checked_value' => 1,
'unchecked_value' => 0,
],
'attributes' => [
'id' => '',
'class' => '',
],
]);
Input filter
$this->add([
'name' => 'enabled',
'required' => true,
'validators' => [
[
'name' => InArray::class,
'options' => [
'haystack' => [true, false],
],
],
],
])

Related

ZF2 - Encoding label from form

I've created a form using ZF2 when my whole system (page & server) is in french and has a ISO-8859-15 encoding. I don't have the power to change this encoding, so I guess we will have to deal with ANSI.
The issue is that when creating my form, I use this piece of code :
public function createAction() {
BootstrapLogger::info(__METHOD__);
$this->layout( 'layout/xhtml' );
$dbAdapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');;
$form = new ActionForm($dbAdapter);
$form->get('submit')->setValue('Créer');
}
and get this error :
Message:
String to be escaped was not valid UTF-8 or could not be converted: Crï¿œer
I don't really understand why, nor how to avoid this.
As I'm guessing it's the same reason that, when creating my form, the labels are also wrongly encoded.
$this->add( array(
'name' => 'act_num',
'type' => 'Text',
'options' => array(
'label' => "N° action",
),
'attributes' => array(
'disabled' => 'disabled',
'class' => 'form-control'
)
));
//ch2 - Libellé de l'action
$this->add( array(
'name' => 'act_label',
'type' => 'Text',
'options' => array(
'label' => "Libellé de l'action",
),
'attributes' => array(
'required' => 'required',
'class' => 'form-control'
)
));
This will give me
Nᅵ action
Libellᅵ de l'action
Same issue with the content of the select (that are populated by the SQLDb [that is in latin1_general_ci]).
Any idea how to fix this ?
Many thanks in advance
Try specifying a different encoding for your form. Not sure how you use your InputFilter, because there are few different ways, but add this for every field.
'validators' => [
[
'name' => 'StringLength',
'options' => [
'encoding' => 'UTF-8',
'min' => 1,
],
],
],

Zend Framework 2 Radio Button null value default

I am using Zend Framework 2, Doctrine Module and SQLServer to build a number of products.
I have a question in relation to Zend\Form\Radio.
I have the following defined in a form:
// boolean $disabled_access
$this->add(array(
'name' => 'disabled_access',
'type' => 'radio',
'options' => array(
'label' => 'Disabled Access',
'value_options' => array('1'=>"Yes", '0' => 'No'),
'allow_empty' => true,
'nullable' => true,
),
'attributes' => array('value' => null),
));
It is bound to a $building entity.
If the value of 'disabled_access' is set to true in the DB, the radio button renders correctly. Similarly if it's is set to false.
However, if the column has a NULL value, the radio button defaults to 'No'. How do I set it up to show all three potential results?
This should be enough -
$this->add(array(
'name' => 'disabled_access',
'type' => 'radio',
'options' => array(
'label' => 'Disabled Access',
'value_options' => array('1'=>'Yes', '0' => 'No'),
),
)
);
If value in database is -
1 -> 'Yes' radio button will be selected,
0 -> 'No' radio button will be selected,
NULL -> none of them will be selected.
Its working for me.
I hope it helps.

Div Hide/Show with radio button click using Zend Form

Here is my code:
class File_Form_AddFile extends Custom_Form {
public function init() {
$translate = Zend_Registry::get('translate');
$this->setTranslator($translate);
$this->setName("addfile");
$this->setMethod('post');
$this->addElement('text', 'title', array(
'filters' => array('StringTrim'),
'validators' => array(
array('StringLength', false, array(0, 50)),
),
'required' => true,
'label' => __('Title') . ':',
));
$this->addElement('radio', 'type', array(
'label'=>__('Applicant Type'),
'multiOptions' => array(
'office' => 'Office',
'community' => 'Community',
'person' => 'Person',
),
'required' => true,
'separator' => '',
'value' => 'office'
));
**// I want this section to show only after 'community' is clicked at above input field.**
$this->addElement('radio', 'community_is_registered', array(
'label'=>__('Registered Community?'),
'multiOptions' => array(
1 => 'Yes',
0 => 'No',
),
'separator' => '',
'value' =>'0'
));
$this->addElement('text', 'name', array(
'filters' => array('StringTrim'),
'validators' => array(
array('StringLength', false, array(0, 100)),
),
'required' => true,
'label' => __('Applicant Name') . ':',
));
$this->addElement('submit', 'save', array(
'required' => false,
'ignore' => true,
'label' => __('Save'),
));
$this->save->removeDecorator('label');
}
}
This is a form to add some information of a file. Here i want to show the section of "Registered Community?" only after the button "Community" is clicked at "Applicant Type". Seeing for help !!
Since you want certain behavior to occur on the client-side based upon certain actions taking place on the client-side, it seems to be fundamentally a client-side question.
Perhaps the easiest thing is to:
Add a certain CSS class to the Registered Community element (or display group, if it's a collection of elements) during server-side form creation.
Use front-end CSS to hide all form elements of that class.
Add a client-side on-click handler to the "Applicant Type" element that removes/changes the class or shows/hides the "Registered Community" section when the "Applicant Type" has the desired value.

Codeigniter form validation using set of rules

I'm trying to create a set of Form validation rules in my Codeigniter project, so that when the validation of the first set fails, the second validation set should not run.
I found this in the CI manual:
$config = array(
'signup' => array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => 'required'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'required'
),
array(
'field' => 'passconf',
'label' => 'PasswordConfirmation',
'rules' => 'required'
),
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'required'
)
),
'email' => array(
array(
'field' => 'emailaddress',
'label' => 'EmailAddress',
'rules' => 'required|valid_email'
),
array(
'field' => 'name',
'label' => 'Name',
'rules' => 'required|alpha'
),
array(
'field' => 'title',
'label' => 'Title',
'rules' => 'required'
),
array(
'field' => 'message',
'label' => 'MessageBody',
'rules' => 'required'
)
)
);
$this->form_validation->set_rules($config);
I know that I can now run the validation of each set separately ($this->form_validation->run('signup') and $this->form_validation->run('email') in this case).
The problem is, that when I use the $config array, errors do not get added to the Form validation class (and thus does not show up) while the form post failed. It did add and show errors when I did not use the set of rules, but just the $this->form_validation->set_rules() method.
What did I do wrong that no error messages are added when entering invalid form data while using a set of rules?
The $config array needs to be in a file called form_validation.php in the application/config directory. It is then loaded automatically when CI is loaded, and passed to the Form validation object when it is created.
The first time the run() method of the FV object is called, if no rules have been set in the FV object, it looks up the config rules it was given on creation, and uses the group indexed by the name passed as argument to run(). All later calls to run() in the same invocation of the CI application, even with different group names, will bypass this check since the rules will now have been set - i.e., you only get to set the rule group once in an invocation.
So you won't be able to create two groups of rules and then call one after the other. You can either call one OR the other.
It might be better to cascade your rules using set_rule() - i.e., add some rules using set_rule(), then validate against them. if they pass, add some more rules and retry validation. You effectively repeat the old rules, knowing they will pass, but that means any failures will be the result of the new rules.
Try array_merge in the form_validation array.
Here if you want two array to combint and gat join validation error. You can use this
$config["form"] = array_merge($config['signup'], $config['email']);
Hope this help.
If someone is facing the same problem try this:
if ($this->form_validation->run('signup') === FALSE) { /* return your errors */ }
$this->form_validation->reset_validation();
$this->form_validation->set_data($data);
if ($this->form_validation->run('email') === FALSE) { /* return your errors */ }
// Do your stuff
You need to reset after each validation to change the rules. You can also use:
$this->form_validation->set_rules($validation_rules);
Note: Set data first and then set rules, it doesn't work the other way around!
hey alwin u need to run the form_validation rules before submitting the form
....
$config = array(
'signup' => array(
array(
'field' => 'username',
'label' => 'Username',
'rules' => 'required'
),
array(
'field' => 'password',
'label' => 'Password',
'rules' => 'required'
),
array(
'field' => 'passconf',
'label' => 'PasswordConfirmation',
'rules' => 'required'
),
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'required'
)
),
'email' => array(
array(
'field' => 'emailaddress',
'label' => 'EmailAddress',
'rules' => 'required|valid_email'
),
array(
'field' => 'name',
'label' => 'Name',
'rules' => 'required|alpha'
),
array(
'field' => 'title',
'label' => 'Title',
'rules' => 'required'
),
array(
'field' => 'message',
'label' => 'MessageBody',
'rules' => 'required'
)
)
);
$this->form_validation->set_rules($config);
///u have to chek form validation getting validate or not
//enter code here
if ($this->form_validation->run() === FALSE) {
$this->load->view('your_view');
} else {$this->ur_controller->method_name();
$this->load->view('whatever ur view');
}
}

zend helper Db_NoRecordExists for multiple table check

I want to check mobile number uniqueness in my two table ..I have added this code but It checking only second one...Is it any other way to validated this in form..
$this->addElement('text', 'mobilenumber', array(`enter code here`
'filters' => array('StringTrim'),
'validators' => array`enter code here`(
array('Db_NoRecordExists', true, array('table' => 'beroe_user', 'field' => 'mobilenumber', 'messages' => array(
'recordFound' => 'mobilenumber already exists'
))),
array('Db_NoRecordExists', true, array('table' => 'beroe_user', 'field' => 'mobilenumber', 'messages' => array(
'recordFound' => 'admin already exists'
))),
),
// 'required' => true,
'label' => 'Phone ',
'maxlength' => '15'
));
I think this is because when we add same validator to an element multiple times the former will be overridden. Check class Zend_Form_Element, addValidator() line 1153
You can create a custom validators as you need. It would be the best thing to do.