Question

I've created two dropdowns field in the system.xml , both of them have the same options, except that one has an extra option: None. This is the xml:

        <field id="printing_option" translate="label" type="select" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="4">
            <label>Printing option</label>
            <source_model>Vendor\Module\Model\Config\Source\PrintingOption</source_model>
        </field>
        <field id="printing_option_2" translate="label" type="select" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="4">
            <label>Printing option 2</label>
            <source_model>Vendor\Module\Model\Config\Source\PrintingOption</source_model>
        </field>

and in my Vendor\Module\Model\Config\Source\PrintingOption I have:

namespace Vendor\Module\Model\Config\Source;
use Magento\Framework\Data\OptionSourceInterface;

class PrintingOption implements OptionSourceInterface
{
    /**
     * Printing options: automatic or manual
     *
     * @return array
     */
    public function toOptionArray() : array
    {
        return [
            // I want to add the none option for my second field
            ['value' => 2, 'label' => __('NONE')], 
            ['value' => 1, 'label' => __('Automatic')],
            ['value' => 0, 'label' => __('Manual')]
        ];
    }
}

I want to add the NONE option only for my second dropdown. Is there a way to do this, instead of creating a new source model ? and to avoid duplicate codes ?

Thnx

Was it helpful?

Solution

Try to do this below way :

system.xml file :

<field id="printing_option" translate="label" type="select" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="4">
            <label>Printing option</label>
            <source_model>Vendor\Module\Model\Config\Source\PrintingOption</source_model>
        </field>
        <field id="printing_option_2" translate="label" type="select" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="4">
            <label>Printing option 2</label>
            <source_model>Vendor\Module\Model\Config\Source\PrintingOption::toOptionsArrayFunction2</source_model>
        </field>

Vendor\Module\Model\Config\Source\PrintingOption.php

<?php

namespace Vendor\Module\Model\Config\Source;

class PrintingOption implements \Magento\Framework\Option\ArrayInterface
{

    /**
     * Return array of options as value-label pairs
     *
     * @return array Format: array(array('value' => '<value>', 'label' => '<label>'), ...)
     */
    public function toOptionArray()
    {
        return [
            [
                'value' => 'labels',
                'label' => 'Labels',
            ],
            [
                'value' => 'dropdown',
                'label' => 'Drop Down',
            ],
        ];
    }

    /**
     * Get options in "key-value" format
     *
     * @return array
     */
    public function toOptionsArrayFunction2()
    {
        return [
            [
                'value' => 'labels',
                'label' => 'Labels',
            ],
            [
                'value' => 'dropdown',
                'label' => 'Drop Down',
            ],
            [
                'value' => 'image',
                'label' => 'Image',
            ],
        ];
    }
}

EXPLANATION

Its working because when Magento tries to load resource model and get its data array, it first checks if there are any methods defined for the source model. If you define a method after your source model with :: sign, it will only call that method to get options.

Check /vendor/magento/module-config/Model/Config/Structure/Element/Field.php::_getOptionsFromSourceModel($sourceModel) function.

But, here it's working. You need to atleast one time use toOptionArray() function in your source model file.

OTHER TIPS

I think it will not be possible to achieve your requirements without separate source_model.

But there is another alternative to add dropdown options in configuration field, without using source_model. If your options are static and not going to change frequently, you can directly use <options> tag in your system.xml file.

<field id="printing_option" translate="label" type="select" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="4">
    <label>Printing option</label>
    <options>
        <option label="Automatic">1</option>
        <option label="Manual">0</option>
    </options>
</field>
<field id="printing_option_2" translate="label" type="select" showInDefault="1" showInWebsite="0" showInStore="0" sortOrder="4">
    <label>Printing option 2</label>
    <options>
        <option label="NONE">2</option>
        <option label="Automatic">1</option>
        <option label="Manual">0</option>
    </options>
</field>
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top