Admin config: แสดงฟิลด์ขึ้นอยู่กับค่าหลายค่าที่เลือก


10

ฉันต้องการแสดงฟิลด์ตามอินพุตแบบเลือกหลายรายการ ... รหัสต่อไปนี้ใช้งานได้หากเลือกเพียงหนึ่งค่า ถ้าฉันเลือกมากกว่าหนึ่งค่ามันจะแสดงเพียงหนึ่งฟิลด์ (เลือกครั้งแรกจากโมเดลต้นทาง)

<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 / รหัส / core / Mage / Adminhtml / บล็อก / เครื่องมือ / แบบฟอร์ม / ธาตุ / 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 / ผู้วิเศษ / 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Ə

ok @ sv3n เจ๋งเจอกันเร็ว ๆ นี้;)
PЯINCƏ

คำตอบ:


12

เหตุผลในการออก

ปัญหาที่คุณเผชิญนั้นเกี่ยวข้องกับฟังก์ชั่น Javascript เพื่อให้ได้ค่าของแอตทริบิวต์แบบเลือกได้หลายแบบ

เขตข้อมูลที่เชื่อถือได้ของวีโอไอพีขึ้นอยู่กับ 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)

เมื่อคุณเลือกตัวเลือกจากหลายคุณสมบัติมันจะส่งกลับเฉพาะค่าที่เลือกแรก

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

ตรวจสอบซอนี้

แม้ว่าคุณจะเลือกตัวเลือกหลายตัวคุณจะได้รับค่าตัวเลือกที่เลือกไว้ก่อนเสมอ

ทางออกสำหรับปัญหา

คุณต้องอัปเดตไฟล์form.jsของ 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แต่ ditn't พบวิธีแก้ปัญหายัง ...
sv3n

2
@ sv3n โปรดตรวจสอบคำตอบที่อัปเดต
Jaimin Sutariya
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.