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

我的梦境 提交于 2019-12-18 05:04:36

问题


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 <depends> tag to make a field show only when a specific value is set in another field.

My Q is how can I make fieldB visible if field A has either value V1 or V2. and are there any other options with the <depends> ?

Also If someone knows where in magento's code this is implemented I would also like to have a look at the code myself.

Thanks


回答1:


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>



回答2:


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




回答3:


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




回答4:


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.



来源:https://stackoverflow.com/questions/4849616/can-a-magento-adminhtml-field-depend-on-more-then-one-field-or-value

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