If you’re a fastidious Magento module developer, you will try to make sure that your module options only reveal the necessary and configured fields to the admin user and hide all the irrelevant stuff. Specifically, I’m referring to Yes/No options that allow the administrator to enable and configure a subsequent option. For example, you have an extension that can show additional field content if an option is enabled and allows for entering the field contents:

Standard options configuration

Standard options configuration

As we can see, the initial state is ‘No’ for the ‘Enable Additional Text’ option, and the textarea is blank. It would be really nice if the whole ‘Additional Text’ row was hidden in this scenario.

We can achieve that by utilizing a front end model for our Yes/No option. Magento provides this mechanism for creating options that depend on certain settings or other dependencies. Some of the built in options are the ‘Allowed Countries’, Enable Flat Catalog Products/Categories and the Tax Destination Calculation ‘State’ option.

We are going to use the front end model to add some logic to enable/disable the textarea and some JavaScript to enable the toggle functionality when the Yes/No drop-down is changed. Note that this is just one, albeit trivial, example of using this technique. Especially since Magento provides the <depends> node for this specific purpose (see the update below).

Using the same tutorial module from our Explain Your Module Configuration Options With Tooltips quick tip, we’ll change our system.xml to read:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <tabs>
        <magebase translate="label" module="custom">
            <label>Magebase</label>
            <sort_order>700</sort_order>
        </magebase>
    </tabs>
    <sections>
        <mbcustom translate="label" module="custom">
            <tab>magebase</tab>
            <label>Magebase Tutorial Options</label>
            <frontend_type>text</frontend_type>
            <sort_order>10</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>1</show_in_store>
            <groups>
                <default translate="label">
                    <label>Conditional Toggle Options</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>10</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>
                    <fields>
                        <mbcustomopt1 translate="label comment">
                            <label>Enable Additional Text</label>
                            <frontend_type>select</frontend_type>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                            <frontend_model>custom/adminhtml_system_config_form_field_customopt1toggle</frontend_model>
                            <sort_order>10</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                            <comment>Select whether to show a text block in the front end.</comment>
                        </mbcustomopt1>
                        <mbcustomopt2 translate="label comment">
                            <label>Additional Text</label>
                            <frontend_type>textarea</frontend_type>
                            <sort_order>20</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>0</show_in_store>
                            <comment>Enter the content for the text block.</comment>
                            <tooltip>Note that the content will be erased if you disable it above, and save.</tooltip>
                        </mbcustomopt2>
                    </fields>
                </default>
            </groups>
        </mbcustom>
    </sections>
</config>

The key to our quick tip is in:

<frontend_model>custom/adminhtml_system_config_form_field_customopt1toggle</frontend_model>

So, now, we’re going to create the front end model class. Incidentally, even though it’s named a ‘model’ class we are going to create it as a Magento Block class since this is how the other built in front end model classes are implemented. Effectively, it is used for template output so it’s appropriate to create a block class for this.

Create Customopt1toggle.php under .../Magebase/Custom/Block/Adminhtml/System/Config/Form/Field/ with the following content:

class Magebase_Custom_Block_Adminhtml_System_Config_Form_Field_Customopt1toggle extends Mage_Adminhtml_Block_System_Config_Form_Field
{

    /**
     * Get element ID of the dependent field to toggle
     *
     * @param object $element
     * @return String
     */
    protected function _getToggleElementId($element)
    {
        return substr($element->getId(), 0, strrpos($element->getId(), 'mbcustomopt1')) . 'mbcustomopt2';
    }
    /**
     * Get element ID of the dependent field's parent row
     *
     * @param object $element
     * @return String
     */
    protected function _getToggleRowElementId($element)
    {
        return 'row_'.$this->_getToggleElementId($element);
    }
    /**
     * Override method to output our custom HTML with JavaScript
     *
     * @param Varien_Data_Form_Element_Abstract $element
     * @return String
     */
    protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
    {
        // If our Yes/No toggle is 'No' then disable the text value field
        if(!$element->getValue() || $element->getValue()!=1) {
            $_frm = $element->getForm();
            $_elm = $_frm->getElement($this->_getToggleElementId($element));
            $_elm->setDisabled('disabled')->setValue('');
        }
        // Get the default HTML for this option
        $html = parent::_getElementHtml($element);
        // Set up additional JavaScript for our toggle action. Note we are using the two helper methods above
        // to get the correct field ID's. They are hard-coded and depend on your option names in system.xml
        $javaScript = "
            <script type=\"text/javascript\">
                Event.observe(window, 'load', function() {
                    enabled=$('{$element->getHtmlId()}').value;
                    if (!enabled || enabled!=1) {
                        $('{$this->_getToggleRowElementId($element)}').hide();
                    } else {
                        $('{$this->_getToggleRowElementId($element)}').show();
                    }
                });
                Event.observe('{$element->getHtmlId()}', 'change', function(){
                    enabled=$('{$element->getHtmlId()}').value;
                    $('{$this->_getToggleElementId($element)}').disabled = (!enabled || enabled!=1);
                    if (!enabled || enabled!=1) {
                        $('{$this->_getToggleRowElementId($element)}').hide();
                    } else {
                        $('{$this->_getToggleRowElementId($element)}').show();
                    }
                });
            </script>";

        $html .= $javaScript;
        return $html;
    }
}

The Varien_Data_Form_Element_Abstract class implements the _getElementHtml() method responsible for generating the HTML for each option element. This is where we can add out override and ‘inject’ some custom code to control the other element as well as the JavaScript to implement the dynamic toggle functionality. The code is self-explanatory.

Basically, we have a couple of helper methods to return our HTML field and row ID’s depending on the names we gave our options in config.xml. The _getElementHtml() method just sets the disabled state of the textarea field if the option is ‘No’ and adds the Prototype JavaScript to add our toggle functionality. The JavaScript code will execute on page load and completely hide the text field if the option is ‘No’ and install an event observer on the Yes/No drop-down to show/hide the text option.

The result of our work would look like this initially:

Toggle options - text hidden

Toggle options - Text Hidden

Selecting ‘Yes’, wil toggle the next field into its visible state:

Toggle options - text revealed

Toggle options - text revealed

Conclusion

We’ve seen how to create a nice little usability enhancement to busy module option pages. You can take this paradigm and enhance it for your own specific purposes. You can study the other examples of the built in Magento options using a frontend_model class for more inspiration and ideas.

One note, the above solution will erase a text option once its saved when the toggle is set to ‘No’. If you’d like to preserve the option, just remove the PHP code setting the text field as disabled as well as the $('{$this->_getToggleElementId($element)}').disabled = (!enabled || enabled!=1); JavaScript line. That should allow the hidden option to be saved.

Update:

The same result as above can be achieved by utilizing the <depends> node in the system.xml as Damián pointed out:

<fields>
    <mbcustomopt1 translate="label comment">
        <label>Enable Additional Text</label>
        <frontend_type>select</frontend_type>
        <source_model>adminhtml/system_config_source_yesno</source_model>
        <sort_order>10</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>1</show_in_website>
        <show_in_store>0</show_in_store>
        <comment>Select whether to show a text block in the front end.</comment>
    </mbcustomopt1>
    <mbcustomopt2 translate="label comment">
        <label>Additional Text</label>
        <frontend_type>textarea</frontend_type>
        <sort_order>20</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>1</show_in_website>
        <show_in_store>0</show_in_store>
        <depends><mbcustomopt1>1</mbcustomopt1></depends>
        <comment>Enter the content for the text block.</comment>
    </mbcustomopt2>
</fields>

However, this article illustrates how you can potentially add custom option processing using the front end model option. This is more relevant for example if you have an option where you need to check more complex conditions or link several options together.

Originally published on magebase.com. Copyright © 2011 Magebase - All Rights Reserved.


Back Older article Newer article

New theme released

Responsive Magento Theme - Gala Marcos

A truly impressive Magento template for fashion store from Galathemes, Gala Marcos. It amazes visitors by modern and high-fashion look, and also, neat design.

Read more

Our services

Installation

Magento Custom Development

Magento is the most powerful eCommerce system offering rich customization possibilities by extensions and modules.

We offer custom extension development performed by our full-time Magento experts to ensure the custom extension developed follow Magento code standard, optimized and pass our quality tests.

Read more

design

Magento Custom Design

Design and development a custom Magento template for your Magento store. Our designers and developers are specialists in Magento Commerce and have strong experience in Magento projects.

We provide all design in PSD files, template package and sample data. We also help you install the theme on your store if required. We start your project instantly and with highest priority.

Read more

Magento Template Conversion

PSD to Magento Theme Conversion

PSD to Magento Theme Conversion is a leading strength of us. We have an intelligent process and experienced staff, so you will save much time.

We easily convert a store designs in PSD format into a fully functional Magento commerce template. Quick and convenient for you to create an online store based on Magento is through "PSD to Magento Theme Conversion" service. We bring the flexibility, user friendly modules, and the extensions to improve the functionality of Magento.

Read more

Development

Magento Site Development

We update our Magento knowledge everyday. Having an excellent knowledge on Magento design, Magento programming and server optimization, we guarantee your project get done perfectly.

We apply the philosophy of agile project management to ensure your project always performs on the right way, you'll get updates frequently, any changes of scope of project can be informed early to minimize risks, time and cost.

Read more

Optimization

Magento Server Optimization

We realy provide the best service for you. Among them are optimized for Magento server is very important. Your ecommerce shop will flexibility and agility absolute. Connecting with customers, processing speed, the gentle query and sensitive to the search engine is very easy

Read more