Configurazione amministratore: mostra il campo in base ai valori di selezione multipla selezionati


10

Voglio visualizzare i campi in base all'input multi-selezione selezionato ... il seguente codice funziona, se viene selezionato un solo valore. Se seleziono più di un valore, mostra solo un campo (prima selezionato dal modello di origine)

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

Codice correlato:

app / code / core / Mage / Adminhtml / blocchi / 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 / mago / 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
Ciao @ sv3n, ti vediamo non troppo, tutto bene?
PЯINCƏ,

ok @ sv3n cool, a presto;)
PЯINCƏ

Risposte:


12

Motivo del problema

Il problema riscontrato è legato alla funzionalità Javascript per ottenere il valore di un attributo a selezione multipla.

I campi affidabili di Magento si basano su Javascript. Creano un JSON con tutti i campi e valori di campi affidabili come di seguito.

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)

Quando si seleziona un'opzione dall'attributo di selezione multipla, viene restituito solo il primo valore selezionato.

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

Controlla questo violino

Anche se selezioni più opzioni, otterrai sempre il primo valore di opzione selezionato.

Soluzione per il problema

Devi aggiornare il tuo file JS form.js per ottenere ciò che si desidera.

Per prima cosa devi aggiungere una nuova funzione che ti porterà tutti i valori selezionati di una selezione multipla invece del solo valore singolo.

Aggiungi una nuova funzione in 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;
}

Ora usa questi valori per verificare con la tua trackChangefunzione nello stesso file. Sostituisci sotto il codice

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

Con questo codice

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

E dovrebbe funzionare per te.


Grazie. Questo lo spiega, ma non lo risolve. Controllato js/adminhtml/form.js, ma non ho ancora trovato una soluzione ...
sv3n

2
@ sv3n, controlla la risposta aggiornata.
Jaimin Sutariya,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.