It is sometimes required to show or hide some fields in admin forms based on the state of other fields. One may wish, for instance, to show the "B" field only if the "A" field is set to "Yes". One may also like to show "C" if "B" is set to "Yes" and "B" is set to "No". Magento gives us a tool to do that easily : the "Form element dependencies mapper"


What you get

Depend block

How it works

You certainly already know how to show or hide fields in system configuration by using the depends node in the system.xml files. It is not as easy for other forms fields! Indeed, in this case, forms are being built with PHP... so XML is no help here! The Magento Core Team has created a system that allows to mimic the dependsfunctionnality in other admin forms. This feature is called "Form element dependencies mapper".

In a form block class (that extends Mage_Adminhtml_Block_Widget_Form), the idea is to:

  • Create, as usual: a Varien_Data_Form, one or several fieldsets, one or several fields.
  • Inject a block of Mage_Adminhtml_Block_Widget_Form_Element_Dependence type in the form_after block that is called by the form template (/app/design/adminhtml/default/default/template/widget/form.phtml)

Commented code

The code below is an extract of the sample module available at the end of this post. Its name is Herve_DependBlock.

<?php  
class Herve_DependBlock_Block_Adminhtml_Form extends Mage_Adminhtml_Block_Widget_Form  
{
    /**
     * CAUTION - This form is not ready for CRUD operations
     * It is just an example in the simpliest form to show the use of dependencies block
     */


    /**
     * Init form
     */
    public function __construct()
    {
        parent::__construct();
        $this->setTitle(Mage::helper('herve_dependblock')->__('Block Information'));
    }

    /**
     * Prepare form
     *
     * @return Mage_Adminhtml_Block_Widget_Form
     */
    protected function _prepareForm()
    {
        // Create a new form
        $form = new Varien_Data_Form();

        // Add a fieldset to this form
        $fieldset = $form->addFieldset(
            'base_fieldset',
            array('legend' => Mage::helper('herve_dependblock')->__('General Information'))
        );

        // Add some fields

        $fieldset->addField(
            'show_children_field',
            'select',
            array(
                'name' => 'show_children_name',
                'label' => Mage::helper('herve_dependblock')->__('Show Children'),
                'title' => Mage::helper('herve_dependblock')->__('Show Children'),
                'options' => Mage::getSingleton('adminhtml/system_config_source_yesno')->toArray()
            )
        );

        $fieldset->addField(
            'show_child_field',
            'select',
            array(
                'name' => 'show_child_name',
                'label' => Mage::helper('herve_dependblock')->__('Show Child'),
                'title' => Mage::helper('herve_dependblock')->__('Show Child'),
                'options' => Mage::getSingleton('adminhtml/system_config_source_yesno')->toArray()
            )
        );

        $fieldset->addField(
            'child_text_field',
            'text',
            array(
                'name' => 'child_text_name',
                'label' => Mage::helper('herve_dependblock')->__('Child Text'),
                'title' => Mage::helper('herve_dependblock')->__('Child Text'),
                'note' => Mage::helper('herve_dependblock')->__('Type "show" and click outside the field')
            )
        );

        $fieldset->addField(
            'child_field',
            'note',
            array(
                'name' => 'child_name',
                'text' => Mage::helper('herve_dependblock')->__('<strong>Surprise!</strong>'),
                'label' => '',
                'title' => Mage::helper('herve_dependblock')->__('Child'),
            )
        );

        // Set form to be rendered in template
        $this->setForm($form);

        // Set block for the "form_after" block in template
        // @see /app/design/adminhtml/default/default/template/widget/form.phtml
        $this->setChild('form_after',

            // The content of the "form_after" block is a Mage_Adminhtml_Block_Widget_Form_Element_Dependence block typ
            $this->getLayout()->createBlock('adminhtml/widget_form_element_dependence')

                /**
                 * Map the form fields to the dependencies block IDs
                 * This is kind of a "form field" => "dependencies block identifier" association
                 */

                // Our form's "show_children_field" is used with the "show_children_depend_id" ID in the dependencies block
                ->addFieldMap('show_children_field', 'show_children_depend_id')

                // Our form's "show_child_field" is used with the "show_child_depend_id" ID in the dependencies block
                ->addFieldMap('show_child_field', 'show_child_depend_id')

                // Our form's "child_field" is used with the "child_depend_id" ID in the dependencies block
                ->addFieldMap('child_field', 'child_depend_id')

                // Our form's "child_text_field" is used with the "child_text_depend_id" ID in the dependencies block
                ->addFieldMap('child_text_field', 'child_text_depend_id')

                /**
                 * Create dependencies
                 * Each addFieldDependence() can be understood like:
                 * "Show this [dependencies block identifier] if this [dependencies block identifier] is [value]
                 *
                 * Defined dependencies do stack. This allows some "AND" statements.
                 */

                // Show 'show_child_depend_id' if 'show_children_depend_id' is '1'
                // In other words, based on the previous mapping: "Show the 'show_child_field' if 'show_children_field' value is 1
                ->addFieldDependence('show_child_depend_id', 'show_children_depend_id', '1')

                // Show 'child_depend_id' if 'show_children_depend_id' is '1'
                ->addFieldDependence('child_depend_id', 'show_child_depend_id', '1')

                // Show 'child_text_depend_id' if 'show_children_depend_id' is '1'
                ->addFieldDependence('child_text_depend_id', 'show_child_depend_id', '1')

                // Show 'child_depend_id' if 'show_children_depend_id' is '1'
                // AND if 'show_child_depend_id' is also '1'
                // AND, for the fum, if the user has typed "show" in 'child_text_depend_id'
                ->addFieldDependence('child_depend_id', 'show_children_depend_id', '1')
                ->addFieldDependence('child_depend_id', 'show_child_depend_id', '1')
                ->addFieldDependence('child_depend_id', 'child_text_depend_id', 'show')
        );

        return parent::_prepareForm();
    }
}
?>