管理员配置:根据选定的多选值显示字段


10

我想显示基于选定的multiselect输入的字段...如果仅选择一个值,则下面的代码将起作用。如果我选择了多个值,则它仅显示一个字段(首先从源模型中选择)

<enabled>
    <label>Enabled</label>
    ...
    <source_model>adminhtml/system_config_source_enabledisable</source_model>
</enabled>

<!-- this gives three options - shop, ebay, amazon -->
<channels>
    ...
    <frontend_type>multiselect</frontend_type>
    <source_model>module/system_config_source_channels</source_model>
    <depends>
        <enabled>1</enabled>
    </depends>
</channels>
<mail_template_shop>
    ...
    <depends>
        <enabled>1</enabled>
        <channels>shop</channels>
    </depends>
</mail_template_shop>
<mail_template_ebay>
    ...
    <depends>
        <enabled>1</enabled>
        <channels>ebay</channels>
    </depends>
</mail_template_ebay>

相关代码:

app / code / core / Mage / Adminhtml / Block / Widget / Form / Element / Dependence.php

/**
 * Add misc configuration options to the javascript dependencies controller
 *
 * @param array $options
 * @return Mage_Adminhtml_Block_Widget_Form_Element_Dependence
 */
public function addConfigOptions(array $options)
{
    $this->_configOptions = array_merge($this->_configOptions, $options);
    return $this;
}

/**
 * HTML output getter
 * @return string
 */
protected function _toHtml()
{
    if (!$this->_depends) {
        return '';
    }
    return '<script type="text/javascript"> new FormElementDependenceController('
        . $this->_getDependsJson()
        . ($this->_configOptions ? ', ' . Mage::helper('core')->jsonEncode($this->_configOptions) : '')
        . '); </script>';
}

/**
 * Field dependences JSON map generator
 * @return string
 */
protected function _getDependsJson()
{
    $result = array();
    foreach ($this->_depends as $to => $row) {
        foreach ($row as $from => $value) {
            $result[$this->_fields[$to]][$this->_fields[$from]] = $value;
        }
    }
    return Mage::helper('core')->jsonEncode($result);
}

js / mage / adminhtml / form.js

/**
 * Observer that watches for dependent form elements
 * If an element depends on 1 or more of other elements, it should show up only when all of them gain specified values
 */
FormElementDependenceController = Class.create();
FormElementDependenceController.prototype = {
    /**
     * Structure of elements: {
     *     'id_of_dependent_element' : {
     *         'id_of_master_element_1' : 'reference_value',
     *         'id_of_master_element_2' : 'reference_value'
     *         'id_of_master_element_3' : ['reference_value1', 'reference_value2']
     *         ...
     *     }
     * }
     * @param object elementsMap
     * @param object config
     */
    initialize : function (elementsMap, config)
    {
        if (config) {
            this._config = config;
        }
        for (var idTo in elementsMap) {
            for (var idFrom in elementsMap[idTo]) {
                if ($(idFrom)) {
                    Event.observe($(idFrom), 'change', this.trackChange.bindAsEventListener(this, idTo, elementsMap[idTo]));
                    this.trackChange(null, idTo, elementsMap[idTo]);
                } else {
                    this.trackChange(null, idTo, elementsMap[idTo]);
                }
            }
        }
    },

    /**
     * Misc. config options
     * Keys are underscored intentionally
     */
    _config : {
        levels_up : 1 // how many levels up to travel when toggling element
    },

    /**
     * Define whether target element should be toggled and show/hide its row
     *
     * @param object e - event
     * @param string idTo - id of target element
     * @param valuesFrom - ids of master elements and reference values
     * @return
     */
    trackChange : function(e, idTo, valuesFrom)
    {
        if (!$(idTo)) {
            return;
        }

        // define whether the target should show up
        var shouldShowUp = true;
        for (var idFrom in valuesFrom) {
            var from = $(idFrom);
            if (valuesFrom[idFrom] instanceof Array) {
                if (!from || valuesFrom[idFrom].indexOf(from.value) == -1) {
                    shouldShowUp = false;
                }
            } else {
                if (!from || from.value != valuesFrom[idFrom]) {
                    shouldShowUp = false;
                }
            }
        }

        // toggle target row
        if (shouldShowUp) {
            var currentConfig = this._config;
            $(idTo).up(this._config.levels_up).select('input', 'select', 'td').each(function (item) {
                // don't touch hidden inputs (and Use Default inputs too), bc they may have custom logic
                if ((!item.type || item.type != 'hidden') && !($(item.id+'_inherit') && $(item.id+'_inherit').checked)
                    && !(currentConfig.can_edit_price != undefined && !currentConfig.can_edit_price)) {
                    item.disabled = false;
                }
            });
            $(idTo).up(this._config.levels_up).show();
        } else {
            $(idTo).up(this._config.levels_up).select('input', 'select', 'td').each(function (item){
                // don't touch hidden inputs (and Use Default inputs too), bc they may have custom logic
                if ((!item.type || item.type != 'hidden') && !($(item.id+'_inherit') && $(item.id+'_inherit').checked)) {
                    item.disabled = true;
                }
            });
            $(idTo).up(this._config.levels_up).hide();
        }
    }
};

1
嗨@ sv3n,我们看到的不是太多,一切都很好吗?
PЯINCƏ

好的@ sv3n很酷,很快见;)
PЯINCƏ17年

Answers:


12

问题的原因

您面临的问题与用于获取multiselect属性值的Javascript功能有关。

Magento的可靠字段基于Javascript。他们使用所有字段和可靠的字段值创建JSON,如下所示。

array (size=2)
  'brandlogo_general_pushonhover' => 
    array (size=2)
      'brandlogo_general_brandlogoenabled' => string '1' (length=1)
      'brandlogo_general_enableautoslide' => string '4' (length=1)
  'brandlogo_general_pager' => 
    array (size=2)
      'brandlogo_general_brandlogoenabled' => string '1' (length=1)
      'brandlogo_general_enableautoslide' => string '10' (length=4)

当您从multiselect属性中选择一个选项时,它仅返回第一个选定的值。

document.getElementById('demoSel').onchange = function(e) {
    alert(document.getElementById('demoSel').value);
}

检查这个小提琴

即使您选择了多个选项,也将始终获得第一个选择的选项值。

解决问题的方法

您需要更新JS文件form.js以实现所需的功能。

首先,您必须添加一个新功能,该功能将使您获得Multiselect的所有选定值,而不仅仅是单个值。

form.js中添加新功能

getSelectValues : function(select) {
    var result = [];
    var options = select && select.options;
    var opt;
    for (var i=0, iLen=options.length; i<iLen; i++) {
        opt = options[i];
        if (opt.selected) {
            result.push(opt.value);
        }
    }
    return result;
}

现在使用这些值来检查trackChange同一文件中的函数。替换下面的代码

for (var idFrom in valuesFrom) {
    var from = $(idFrom);
    if (valuesFrom[idFrom] instanceof Array) {
        if (!from || valuesFrom[idFrom].indexOf(from.value) == -1) {
            shouldShowUp = false;
        }
    } else {
        if (!from || from.value != valuesFrom[idFrom]) {
            shouldShowUp = false;
        }
    }
}

有了这个代码

for (var idFrom in valuesFrom) {
    var from = $(idFrom);
    if (from.tagName === 'SELECT' && from.className.indexOf('multiselect') > -1) {
        var elementValues = this.getSelectValues(from);
        if (!from || elementValues.indexOf(valuesFrom[idFrom]) <= -1) {
            shouldShowUp = false;
        }
     } else {
        if (valuesFrom[idFrom] instanceof Array) {
            if (!from || valuesFrom[idFrom].indexOf(from.value) == -1) {
                shouldShowUp = false;
            }
        } else {
            if (!from || from.value != valuesFrom[idFrom]) {
                shouldShowUp = false;
            }
        }
    }
}

它应该为您工作。


谢谢。这可以解释它,但不能解决。已检查js/adminhtml/form.js,但尚未找到解决方案...
sv3n

2
@ sv3n,请检查更新的答案。
Jaimin Sutariya
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.