ZF-4624: Conditions with Zend_Form

Description

!http://nabble.com/file/p19177733/…!

While trying to do some conditions with Zend_Form I figured out that this is actually not possible. The idea was to have two different Subforms. The main form containing only one element, two radio buttons. When the first radio button is selected, only the first Subform should be validated and the second ignored. When the second radio button is selected, it should be just the other way around. The major reason why this was not possible is that you cannot display the radio buttons between Subforms (as they are one element). The only way I see you can achieve this is by doing it hardcoded in a ViewScript but then it cannot be validated.

Radio buttons containing none Subform should also be allowed and it should work with other elements as well, for example a dropdown list. Later on dojo could be used to display only the selected Subform.

Forum thread for this issue: http://nabble.com/-Zend-Form--Conditional-SubForms…

Comments

{quote}The major reason why this was not possible is that you cannot display the radio buttons between Subforms (as they are one element). The only way I see you can achieve this is by doing it hardcoded in a ViewScript but then it cannot be validated.{quote} You can:


class Foo extends Zend_Form
{
    public function init()
    {
        // Radio button
        $this->addElement(
            'radio',
            'first',
            array(
                'name'         => 'switch',
                'multiOptions' => array(
                    1 => 'First',
                ),
            )
        );
        
        // First subform
        $subform1 = new Zend_Form_SubForm();
        $subform1->addElement(
            'text',
            'qux',
            array(
                'label'    => 'Qux',
                'required' => true,
            )
        );
        $this->addSubForm($subform1, 'subform1');
        
        // Radio button
        $this->addElement(
            'radio',
            'second',
            array(
                'name'         => 'switch',
                'multiOptions' => array(
                    2 => 'Second',
                ),
            )
        );      
        
        // Second subform
        $subform2 = new Zend_Form_SubForm();
        $subform2->addElement(
            'text',
            'qux',
            array(
                'label'    => 'Qux',
                'required' => true,
            )
        );
        $this->addSubForm($subform2, 'subform2');
        
        // Submit button
        $this->addElement(
            'submit',
            'submit',
            array(
                'label'   => 'Send',
                'irgnore' => true,
            )
        );
    }
    
    public function isValid($data)
    {
        if (isset($data['switch']) && 1 == $data['switch']) {
            foreach ($this->getSubForm('subform2') as $element) {
                if ($element instanceof Zend_Form_Element) {
                    $element->setRequired(false);
                }
            }
        }
        if (isset($data['switch']) && 2 == $data['switch']) {
            foreach ($this->getSubForm('subform1') as $element) {
                if ($element instanceof Zend_Form_Element) {
                    $element->setRequired(false);
                }
            }
            $this->getElement('second')->setValue('1');
        }
        
        $result = parent::isValid($data);
        
        // Workaround to set values for the checkboxes (element name != name attribute)
        if (isset($data['switch']) && 1 == $data['switch']) {
            $this->getElement('first')->setValue('1');
        }
        if (isset($data['switch']) && 2 == $data['switch']) {
            $this->getElement('second')->setValue('2');
        }
        
        return $result;
    }
}