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

*爱你&永不变心* 提交于 2019-11-29 07:40:01

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>

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=","

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

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!