может ли поле magento adminhtml зависеть от более чем одного поля или значения?

В http://alanstorm.com/magento_system_configuration_in_depth_tutorial @AlanStorm дает очень хорошее руководство по настройке системы.

Он также объясняет, как использовать тег ‹depends>, ​​чтобы поле отображалось только тогда, когда в другом поле установлено определенное значение.

Мой вопрос заключается в том, как сделать поле B видимым, если поле A имеет значение V1 или V2. и есть ли другие варианты с ‹depends>?

Кроме того, если кто-то знает, где в коде magento это реализовано, я также хотел бы сам взглянуть на код.

Спасибо


person epeleg    schedule 31.01.2011    source источник


Ответы (4)


Есть лучший способ, но вам нужно будет переопределить файлы ядра.

Переопределите метод в следующем файле 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;
}

В файле app\code\core\Mage\Adminhtml\Block\System\Config\Form.php измените метод 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);
                }
            }

Измените файл javascript 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();
    }
}

Используйте следующий синтаксис для зависимости нескольких значений от вашего xml

                            <depends>
                            <field1>
                                <val1>text</val1>
                                <val2>radio</val2>
                            </field1>
                        </depends>
person Andrew Aculana    schedule 28.04.2011
comment
Спасибо, Эндрю. Я не проверял это решение, но оно выглядит надежным. Если кто-то действительно пробовал это, пожалуйста, напишите комментарий. - person epeleg; 04.05.2011
comment
Я попробовал это, и это ПОЧТИ работало. Вероятно, это потому, что я использую 1.6.2.0, и это решение предназначалось для более ранней версии Magento. В любом случае, проверьте мой ответ ниже, если вам интересно. Теперь это работает для меня. Спасибо, Андрей! - person pancake; 08.03.2012

Если я правильно понимаю примечания к выпуску из Magento 1.7.0.1, эта функциональность была реализована (http://goo.gl/ZgHG0). Я успешно протестировал его на Magento CE 1.7.0.2.

Вы должны объявить параметр-разделитель в поле зависимости следующим образом:

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

Обратите внимание, что depends_from_field_value_1 и depends_from_field_value_2 разделены запятой, то есть тем символом, который объявлен в separator=",".

person Hervé Guétin    schedule 06.08.2012

Я не знаю, где в статье Алана это объясняется, но вот как я это делаю: это всего лишь немного javascript.
В своей группе вы помещаете тег комментария со встроенным javascript в .
Например, вот мой код, который проверяет значение одного поля, чтобы показать (или нет) другое:

<?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>

как видите, я пишу небольшую функцию, которая проверяет значение одного поля, чтобы определить, показывать другое или нет. Затем я связываю событие onchange с функцией и запускаю функцию для отображения правильных полей при загрузке страницы.
Для ваших нужд просто добавьте условие в функцию js.
Надеюсь, это поможет.

person OSdave    schedule 31.01.2011
comment
Однако, похоже, я не справился с побегом на моем Q должным образом, и «зависит» был невидим в обоих местах. поэтому я исправил вопрос и все еще надеюсь, что кто-нибудь сможет помочь с использованием тега «зависит». Обратите внимание, что трюк с кодом в комментариях затрудняет перевод комментариев (что может быть не проблемой, если вы поместите этот код в комментарий к полю, которое на самом деле не имеет реального комментария). - person epeleg; 31.01.2011
comment
как ни странно, при комментировании ‹depends› можно писать как есть. в то время как при размещении Q он должен быть написан в зависимости от › или он станет невидимым html. - person epeleg; 31.01.2011
comment
@epeleg, используйте обратные кавычки ` вокруг тегов, чтобы WYSIWYG не интерпретировал их как HTML. - person clockworkgeek; 31.01.2011
comment
хорошо, теперь это имеет больше смысла :) вы пытались добавить второй тег в ‹depends›? - person OSdave; 01.02.2011
comment
Я пробовал <depends><field>v1,v2</field></depends> и <depends><field>v1</field><field>v2</field></depends>. Если бы я мог найти, где это реализовано в коде, возможно, это могло бы пролить свет на полный синтаксис. - person epeleg; 02.02.2011

Ответ Андрея почти добился цели. У меня сейчас 1.6.2.0, и я изменил метод initFields() в app\code\core\Mage\Adminhtml\Block\System\Config\Form.php следующим образом:

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);
        }
    }
}

Также нет необходимости редактировать файлы ядра. Я переопределил тему администратора, вставив собственную версию form.js, и переписал два класса PHP. используя config.xml пользовательского модуля.

person pancake    schedule 08.03.2012