can a magento adminhtml field depend on more then one field or value?

前端 未结 4 1591
名媛妹妹
名媛妹妹 2020-12-17 03:40

In http://alanstorm.com/magento_system_configuration_in_depth_tutorial @AlanStorm gives a very good tutorial for system configuration.

He also explains how to use a

相关标签:
4条回答
  • 2020-12-17 03:56

    If I correctly understand release notes from Magento 1.7.0.1, this functionnality has been implemented (http://goo.gl/ZgHG0). I have succeddfully tested it on a Magento CE 1.7.0.2.

    You must declare a separator parameter in the field dependancy like this :

    <depends>
        <depends_from_field separator=",">
            depends_from_field_value_1,depends_from_field_value_2
        </depends_from_field>
    </depends>
    

    Note that depends_from_field_value_1 and depends_from_field_value_2 are separated by a comma, the exact symbol that is declared in separator=","

    0 讨论(0)
  • 2020-12-17 04:03

    There is a better way, but you will need to override the core files

    Override the method under the following file app\code\core\Mage\Adminhtml\Block\Widget\Form\Element\Dependence.php

        public function addFieldDependence($fieldName, $fieldNameFrom, $refValues)
    {
        /*
        if (is_array($refValues)) {
            Mage::throwException('Dependency from multiple values is not implemented yet. Please fix to your widget.xml');
        }
        */
        $this->_depends[$fieldName][$fieldNameFrom] = $refValues;
        return $this;
    }
    

    On the app\code\core\Mage\Adminhtml\Block\System\Config\Form.php Modify the method initFields

    if ($e->depends) {
                    foreach ($e->depends->children() as $dependent) {
                        $dependentId = $section->getName() . '_' . $group->getName() . '_' . $fieldPrefix . $dependent->getName();
                        if ($dependent->count()) {
                            $dependentValue = (array) $dependent;
                            $dependentValue = array_values($dependentValue);
                        } else {
                            $dependentValue = (string) $dependent;
                        }
    
                        $this->_getDependence()
                            ->addFieldMap($id, $id)
                            ->addFieldMap($dependentId, $dependentId)
                            ->addFieldDependence($id, $dependentId, $dependentValue);
                    }
                }
    

    Modify the javascript file js\mage\adminhtml\form.js

    trackChange : function(e, idTo, valuesFrom)
    {
        // define whether the target should show up
        var shouldShowUp = true;
        for (var idFrom in valuesFrom) {
    
            if (valuesFrom.hasOwnProperty(idFrom)) {
                if (typeof(valuesFrom[idFrom])=="object") {
                    shouldShowUp = false;
                    for(var idVal in valuesFrom[idFrom]) {
                        if (valuesFrom[idFrom].hasOwnProperty(idVal)) {
                            if (typeof(idVal)!="undefined" && ($(idFrom).value == valuesFrom[idFrom][idVal])) {
                                shouldShowUp = true;
                            }
                        }
                    }
                } else if (typeof(valuesFrom[idFrom])=="string") {
                    if ($(idFrom).value != valuesFrom[idFrom]) {
                        shouldShowUp = false;
                    }
                }
            }
            /*
            if ($(idFrom).value != valuesFrom[idFrom]) {
                shouldShowUp = false;
            }
            */
        }
    
        // toggle target row
        if (shouldShowUp) {
            $(idTo).up(this._config.levels_up).select('input', 'select', 'td').each(function (item) {
                if (!item.type || item.type != 'hidden') { // don't touch hidden inputs, bc they may have custom logic
                    item.disabled = false;
                }
            });
            $(idTo).up(this._config.levels_up).show();
        } else {
            $(idTo).up(this._config.levels_up).select('input', 'select', 'td').each(function (item){
                if (!item.type || item.type != 'hidden') { // don't touch hidden inputs, bc they may have custom logic
                    item.disabled = true;
                }
            });
            $(idTo).up(this._config.levels_up).hide();
        }
    }
    

    Use the following syntax for multiple values dependency on your xml

                                <depends>
                                <field1>
                                    <val1>text</val1>
                                    <val2>radio</val2>
                                </field1>
                            </depends>
    
    0 讨论(0)
  • 2020-12-17 04:06

    Andrew's answer almost did the trick. I'm on 1.6.2.0 right now and I modified the initFields() method in app\code\core\Mage\Adminhtml\Block\System\Config\Form.php as follows:

    if ($e->depends) {
        foreach ($e->depends->children() as $dependent) {
            Mage::log((array)$dependent);
            $dependentId = $section->getName()
                . '_' . $group->getName()
                . '_' . $fieldPrefix
                . $dependent->getName();
    
            if ($dependent->hasChildren()) {
                $dependentValue = (array) $dependent;
                $dependentValue = array_values($dependentValue);
            } else {
                $dependentValue = (string) $dependent;
            }
    
            $shouldBeAddedDependence = true;
            $dependentFieldName      = $fieldPrefix . $dependent->getName();
            $dependentField          = $group->fields->$dependentFieldName;
            /*
             * If dependent field can't be shown in current scope and real dependent config value
             * is not equal to preferred one, then hide dependence fields by adding dependence
             * based on not shown field (not rendered field)
             */
            if (!$this->_canShowField($dependentField)) {
                $dependentFullPath = $section->getName()
                    . '/' . $group->getName()
                    . '/' . $fieldPrefix
                    . $dependent->getName();
                if (is_array($dependentValue)) {
                    foreach ($dependentValue as $dependentOption) {
                        $shouldBeAddedDependence |= $dependentOption != Mage::getStoreConfig(
                            $dependentFullPath,
                            $this->getStoreCode()
                        );
                    }
                } else {
                    $shouldBeAddedDependence = $dependentValue != Mage::getStoreConfig(
                        $dependentFullPath,
                        $this->getStoreCode()
                    );
                }
            }
            if($shouldBeAddedDependence) {
                $this->_getDependence()
                    ->addFieldMap($id, $id)
                    ->addFieldMap($dependentId, $dependentId)
                    ->addFieldDependence($id, $dependentId, $dependentValue);
            }
        }
    }
    

    Also it's not necessary to edit the core files. I overrode the admin theme to insert my own version of form.js and rewrote the two PHP classes using the config.xml of a custom module.

    0 讨论(0)
  • 2020-12-17 04:09

    I'm not sure where in Alan's article it's explained, but there is how I do it: it's just a bit of javascript.
    In your group you put a comment tag with the javascript embedded into .
    For example, here is my code that checks the value of one field in order to show (or not) another one:

    <?xml version="1.0" encoding="UTF-8"?>
    <config>
        <sections>
            <points_options translate="label" module="points">
                <tab>general</tab>
                <label>Loyalty Points</label>
                <frontend_type>text</frontend_type>
                <sort_order>1002</sort_order>
                <show_in_default>1</show_in_default>
                <show_in_website>1</show_in_website>
                <show_in_store>1</show_in_store>
                <groups>
                    <config_points translate="label">
                        <label>Configuration</label>
                        <comment><![CDATA[
                            <script type="text/javascript">
                                checkExpirationPeriod = function() {
                                    if ($('points_options_config_points_expiration_period').getValue() > 0) {
                                        $('points_options_config_points_expiration_reminder').up(1).appear();
                                    } else {
                                        $('points_options_config_points_expiration_reminder').up(1).fade();
                                    }
                                }
    
                                Event.observe(window, 'load', function() {
                                    Event.observe('points_options_config_points_expiration_period', 'change', checkExpirationPeriod);
                                    checkExpirationPeriod();
                                })
                            </script>
                        ]]></comment>
    

    as you can see, I write a small function which check one field's value to determine if show another one or not. I then link the onchange event to the function and trigger the function to show correct fields as the page is loaded.
    For your needs, just add the condition in the js function.
    Hope That Helps

    0 讨论(0)
提交回复
热议问题