ZF-5609: Zend_Form_Element_Checkbox checkedValue is not set

Description

I have trouble with Zend_Form_Element_Checkbox; I have a custom Form, and I want to add a Zend_Form_Element_Checkbox like this:

$agreement = new Zend_Form_Element_Checkbox('agreement');
$agreement->setLabel('cguLabel') ->setCheckedValue('1') ->setUncheckedValue('0') ->setValue('0'); $this->addElement($agreement);

In my view I do this:(I have the default Decorator):

<?= $this->registerForm->agreement->renderViewHelper() ?>

This is the generate HTML:

So because the input's value is set to 0, I can't know when the checkbox is checked... I use the renderViewHelper because our graphiste made some template, and I wanr to display each party of the Element like I want where I want. After some debugging, I can't fix this comportement with put this line in commentary:

// In Zend/View/Helper/FormCheckbox.php // In function determineCheckboxInfo

if (is_array($checkedOptions)) { if (array_key_exists('checked', $checkedOptions)) { $checkedValue = (string) $checkedOptions['checked']; unset($checkedOptions['checked']); } if (array_key_exists('unChecked', $checkedOptions)) { $unCheckedValue = (string) $checkedOptions['unChecked']; unset($checkedOptions['unChecked']); } if (null === $checkedValue) { $checkedValue = array_shift($checkedOptions); } if (null === $unCheckedValue) { $unCheckedValue = array_shift($checkedOptions); } // Comment these two lines //} elseif ($value !== null) { // $unCheckedValue = self::$_defaultCheckedOptions['unChecked']; } else { $checkedValue = self::$_defaultCheckedOptions['checked']; $unCheckedValue = self::$_defaultCheckedOptions['unChecked']; }

After commenting these line, the html ouput is good:

Is this a bug, or i made a mistake somewhere ?

Comments

Sorry for the unformated code, I re-post it:



// In function determineCheckboxInfo
// Checked/unchecked values
$checkedValue   = null;
$unCheckedValue = null;
if (is_array($checkedOptions)) {
    if (array_key_exists('checked', $checkedOptions)) {
        $checkedValue = (string) $checkedOptions['checked'];
        unset($checkedOptions['checked']);
    }
    if (array_key_exists('unChecked', $checkedOptions)) {
        $unCheckedValue = (string) $checkedOptions['unChecked'];
        unset($checkedOptions['unChecked']);
    }
    if (null === $checkedValue) {
         $checkedValue = array_shift($checkedOptions);
    }
    if (null === $unCheckedValue) {
         $unCheckedValue = array_shift($checkedOptions);
    }
// Comment these two next lines
//} elseif ($value !== null)  {
//    $unCheckedValue = self::$_defaultCheckedOptions['unChecked'];
} else {
    $checkedValue   = self::$_defaultCheckedOptions['checked'];
    $unCheckedValue = self::$_defaultCheckedOptions['unChecked'];
}

Nobody for helping me ?

Patience, please -- there's a huge backlog of bugs, and we can't address all bugs immediately. In this particular case, I know that there are at least two other issues reporting similar problems that also need to be addressed, and I will need to link each of these to ensure that the bugfix addresses each.

Ok no probleme, sorry for my impatience. Good luck and thanks for your good work Matthew ;)

Hi Matthew,

Part of the bug is that the render() method of Zend_Form_Element_Checkbox sets the options 'checked' and 'unChecked' correctly before rendering. This is obviously the wrong place to do this.


public function render(Zend_View_Interface $view = null)
{
    $this->options = array(
        'checked'   => $this->getCheckedValue(),
        'unChecked' => $this->getUncheckedValue(),
    );
    return parent::render($view);
}

My proposed fix: let the constructor call setCheckedValue('1') and setUncheckedValue('0') by default, and add the following lines:

    
public function setCheckedValue($value)
{
    $this->_checkedValue = (string) $value;
    // add this:
    $this->options['checked'] = $this->_checkedValue;
    return $this;
}

/* ... snip ... */
public function setUncheckedValue($value)
{
    $this->_uncheckedValue = (string) $value;
    // add this:
    $this->options['unChecked'] = $this->_uncheckedValue;
    return $this;
}

And remove the render() method from Zend_Form_Element_Checkbox.

The neater fix would be to let Zend_View_Helper_FormCheckbox use the same naming scheme for the options as Zend_Form_Element_Checkbox (which is the root of the problem)

Maybe I'm off base here, but it seems at least part of this problem is inconsistency in not only naming, but case as well. In some places, checked and unchecked values are called just that, checked and unchecked. Right away this seems to be asking for trouble because checked is also an attribute. Some places they are called checkedValue and uncheckedValue, and then in others they are called checkedValue and unCheckedValue.

(this is from 1.8.0)

Dojo/View/Helper/CheckBox.php:62: * @param array $checkedOptions Should contain either two items, or the keys checkedValue and unCheckedValue Dojo/Form/Element/CheckBox.php:55: protected $_checkedValue = '1'; Dojo/Form/Element/CheckBox.php:61: protected $_uncheckedValue = '0'; Dojo/Form/Element/CheckBox.php:80: if (array_key_exists('checkedValue', $options)) { Dojo/Form/Element/CheckBox.php:84: if (array_key_exists('uncheckedValue', $options)) { Dojo/View/Helper/CheckBox.php:92: $html .= $this->_renderHiddenElement($id, $checkboxInfo['unCheckedValue']); View/Helper/FormCheckbox.php:45: 'checked' => '1', View/Helper/FormCheckbox.php:46: 'unChecked' => '0' View/Helper/FormCheckbox.php:92: $xhtml = $this->_hidden($name, $checkedOptions['unCheckedValue']); View/Helper/FormCheckbox.php:159: 'unCheckedValue' => $unCheckedValue,

In general there seems to be a bit of an anything goes policy for camel casing. we have Checkbox and CheckBox, as well as Multiselect and MultiCheckbox.

That aside, I am seeing this same problem in Dojo Check[Bb]oxes, and need to get this working. I will get my CLA sent in ASAP and other acronyms. If someone (Matthew?) would be so kind as to point me toward the previously mentioned other issues, I would be happy to get out my wrenches and bend some metal.

Sean

This patch (May-27-2009.patch) attempts to bring case and naming consistency to checkedValue and uncheckedValue in:

View/Helper/FormCheckbox.php Form/Element/Checkbox.php Dojo/View/Helper/CheckBox.php Dojo/Form/Element/CheckBox.php

I'm still poking around finding the root source of the problem in Dojo CheckBox. It appears that the checkedValue and uncheckedValue should be getting passed into the options array somewhere along the way and they are not, or they got passed in and then got removed.

This patch includes changes to setOptions in both Form/Element/Checkbox.php and in Dojo/Form/Element/CheckBox.php to remove the overriden render and set the options for checkedValue and uncheckedValue in setOptions instead and let the parent render method do the work

Also includes all the changes in the previous patch file. So far it's working for me.

I meant, "This patch (May-27-2009-2nd.patch)" in the previous comment.

I looked it over a little and reworked the patch (May-28-2009.patch) to use Gerard's suggestion to set the options for checkedValue and uncheckedValue in setCheckedValue and setUncheckedValue, otherwise calling one of them after calling setOptions might mangle things. Also, had to check to be sure options was an array before setting.

Yesterday I also bumped into this bug. Took me a few hours to see what was wrong (including a ZF update to the latest version, hoping that would fix it - but it didn't ;)). It would be nice if this can be fixed soon. I've got the feeling that more people will encounter this behaviour.

Thanks :)

I've applied the most recent patch, though with some modifications (the $options array needs to be present by default for the default use case (not setting either value) to work correctly). Patch has been ported to the 1.9 release branch as well.