Main image
7th December
2010
written by Ricky Stevens

Recently at work we came across an issue using Zend Frameworks Form builder – Zend Form. We were creating a form which contained a checkbox and this checkbox had to be checked for the form to be valid. In other words, if the checkbox wasn’t checked, the form should fail validation. Simple Eh?

This sounds easy, and our initial reaction was to use the setRequired() method, as seen in the example below.

  1. $objForm = new Zend_Form();
  2.  
  3. $objForm->setMethod('post');
  4.  
  5. $objCheck = $objForm->createElement('checkbox', 'test')
  6.                     ->setRequired(true);
  7.  
  8. $objForm->addElement($objCheck);

Bizarrely, this didn’t do the trick, and the form validation result would be valid even when the checkbox wasn’t checked. After doing a little research, we found the path to the answer on the Zend Framework issue tracker. This dilema is in part due to the way Zend Form uses  Zend_Validate_NotEmpty as a validator to check for an empty value, when an element is marked as Required. By default, the Zend Form Checkbox Element has these 2 properties in its core class:

  1. /**
  2.  * Value when not checked
  3.  * @var string
  4.  */
  5. protected $_uncheckedValue = '0';
  6.  
  7. /**
  8.  * Current value
  9.  * @var string 0 or 1
  10.   */
  11. protected $_value = '0';

As you can see, the Zend Form Checkbox element by default has a value of ‘0‘, which is encased by quotes to make it a string rather than an integer. It is then passed through Zend_Validate_NotEmpty, and is validated by the following lines of code;

  1. if ($type >= self::STRING) {
  2.   $type -= self::STRING;
  3.   if (is_string($value) && ($value == '')) {
  4.     $this->_error(self::IS_EMPTY);
  5.     return false;
  6.   }
  7. }

As you can probably see at this stage, ‘0‘ is both a string and not equal to ”, so it will pass the validation, and be counted as a valid response. It makes sense to a certain extent, but its a bit of a red herring when it comes to ensuring a checkbox is ticked.

The easiest solution we came up with was to use Zend_Validate_InArray to ensure the value we wanted was passed. This may seem like overkill if all we want to check for is ‘1‘, but if we have a series of checkboxes with different values, and one or more must be selected, this method will also work.

  1. $objForm = new Zend_Form();
  2.  
  3. $objForm->setMethod('post');
  4.  
  5. $objCheck = $objForm->createElement('checkbox', 'test');
  6.  
  7. $objCheck->addValidator(new Zend_Validate_InArray(array(1)), false);
  8.  
  9. $objForm->addElement($objCheck);

This array can also be expanded if there are multiple values  that can be selected from, and one is required. As ‘0‘ is the default value set by the Zend Form Checkbox element, this will fail the validation if the checkbox isn’t checked.

I fully acknowledge this probably isn’t the most elegant method of accomplishing this task, so if you have any improvements or suggestions, please leave a comment!

10 Comments

  1. Amine
    23/02/2011

    Thanks a lot Ricky! That save me time!

  2. nick
    17/03/2011

    Thanks a bunch! Great help.

  3. 486
    21/03/2011

    What I do is set the uncheckedValue to an empty string.
    $objCheck->setUncheckedValue(”);

  4. 15/04/2011

    Ran into this issue today and found your article. Worked perfect. Thanks!

  5. Jeremy
    06/06/2011

    You can also add an error message to the element to make the message more useful. eg.

    $objCheck->addErrorMessage(‘Please tick box to confirm the settings are correct’);

  6. hey
    15/06/2011

    I would prefer to use solutin propsed by user 486 I think in this case have more sense.

  7. anoop
    28/06/2011

    thanx @486…i used
    $objCheck->setUncheckedValue(”)
    ->setRequired(true)
    ->addErrorMessage(‘Please tick box to confirm the settings are correct’);

  8. 23/07/2011

    Thanks for this blog post — 486′s solution seems like less of a hack, though, since you don’t have to change the error message so it doesn’t talk about the heap.

  9. s7anley
    18/09/2012

    I preffer set uncheckeValue like this http://pastie.org/4747150

  10. 26/04/2013

    Hi,

    I prefer Zend_Validate_Identical. Identical is just better fits for this type of validation, looks much prettier:
    http://framework.zend.com/manual/1.12/en/zend.validate.set.html#zend.validate.set.identical

    You can change validator’s default messages, so if you don’t want to see the “Token” word in your error, here is the solution:
    http://framework.zend.com/manual/1.12/en/zend.validate.messages.html

Leave a Reply