Magento 2 - Helper function to prepare data for backend multiselect field

by tecjam   Last Updated January 23, 2019 10:09 AM

I'm trying to use a stores allowed currencies to create a multiselect with these values for a custom module.

Now my question is, how do I best prepare the data array for the mutliselect field?

I suppose the array passed to the multiselect form has to have the following structure:

    $values = array(

        array( // option group
            'label' => 'Group 1',
            'value' =>
                array(
                    array( // Option 1
                        'value' => '1',
                        'label' => 'Option 1'
                    ),
                    array( // Option 2
                        'value' => '2',
                        'label' => 'Option 2'
                    )
                )
        ),

        array( // option group
            'label' => 'Group 2',
            'value' =>
                array(
                    array(
                        'value' => '3',
                        'label' => 'Option 3'
                    ),
                    array(
                        'value' => '4',
                        'label' => 'Option 4'
                    )
                )
        ),
    );

So for example, in my custom Class I want to return all allowed store currencies. I get the data using

$allowedCurrencies = $this->scopeConfig->getValue('currency/options/allow');

So now I need to format this into an array that can be used to create a multiselect field.

Is there a predefined helper class in Magento to prepare / format data for multiselect fields, or do I need to write this from scratch?

I know I could just output all available currencies again using the following in the system.xml

<source_model>Magento\Config\Model\Config\Source\Locale\Currency</source_model>

EDIT:

I've tried to implement David's answer below, but I have not managed. Here is my source model - as you can see I still use my own parsing hack in the getAllowedCurrencies() function.

use Magento\Framework\App\Config\ScopeConfigInterface;

/**
 * Class Config
 *
 * @package Name\MyModule\Model\Config\Backend
 */
class Config implements \Magento\Framework\Data\OptionSourceInterface
{
    /**
     * @var \Magento\Framework\App\Helper\Context
     */
    private $context;

    /**
     * @var ScopeConfigInterface
     */
    private $scopeConfig;

    /**
     * @param \Magento\Framework\App\Helper\Context $context
     */
    public function __construct(\Magento\Framework\App\Helper\Context $context)
    {
        $this->context = $context;
        $this->scopeConfig = $context->getScopeConfig();
    }

    /**
     * Get allowed currencies
     *
     * @return  array of allowed Currencies
     *
     **/
    public function getAllowedCurrencies()
    {
        $allowedCurrencies = $this->scopeConfig->getValue('currency/options/allow');
        $allowedCurrencies = explode(",", $allowedCurrencies);

        $options = [];
        foreach($allowedCurrencies as $k=>$v)
        {
            $options[] = ['value' => $v, 'label' => $v];
        }

        return $options;
    }


    /**
     * Admin Config action
     *
     * @return array
     */
    public function toOptionArray()
    {
        return $this->getAllowedCurrencies();
    }
}


Answers 2


build a Source Model for this like this one for example:

https://github.com/magento/magento2/blob/develop/app/code/Magento/Cms/Model/Config/Source/Page.php

Instead of the ArrayInterface you should use the

Magento\Framework\Data\OptionSourceInterface

because of: https://github.com/magento/magento2/blob/develop/lib/internal/Magento/Framework/Option/ArrayInterface.php#L9

in that interface also the desired array structure is described

https://github.com/magento/magento2/blob/develop/lib/internal/Magento/Framework/Data/OptionSourceInterface.php#L16

David Verholen
David Verholen
February 08, 2016 15:46 PM

Here is a better way

Add your field in system

<field id="currency" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="10"  translate="label comment" type="multiselect">
    <label>Currency</label>
    <source_model>Namespace\Modulename\Model\Config\Source\Currency</source_model>
</field>

Your Source Model File

<?php
namespace Namespace\Modulename\Model\Config\Source;

use Magento\Framework\Option\ArrayInterface;

class Currency implements ArrayInterface {   

    /**
     * @var CollectionFactory
     */
    public $currency;

    /**
     * @param \Magento\CurrencySymbol\Model\System\Currencysymbol $currency
     */
    public function __construct(
        \Magento\CurrencySymbol\Model\System\Currencysymbol $currency
    ) {
        $this->currency = $currency;
    }

    /**
     * Return currency symbol properties array based on config values
     *
     * @return array
     */
    protected function getCurrency()
    {
        return $this->currency->getCurrencySymbolsData();
    }

    /**
     * @return array
     */
    public function toOptionArray()
    {
        $currency = $this->getCurrency();
        $options = [];
        foreach ($this->getCurrency() as $code => $currency) {
            $options[$code] = [
                'label' => $currency['displayName'],
                'value' => $code
            ];
        }

        return $options;
    }
}
Priyank
Priyank
October 28, 2016 05:17 AM

Related Questions


Updated January 21, 2019 14:09 PM

Updated March 26, 2017 08:09 AM

Updated May 30, 2017 05:09 AM

Updated February 21, 2018 14:09 PM

Updated August 11, 2018 05:09 AM