Magento – Set default values for a multiselect ui-component

default valuesmagento2magento2.2uicomponent

I have a custom entity in my magento 2 install.
And one of the fields in this entity is of type multiselect and contains the list of all countries.
I'm using the ui-components for my admin form.
Since there are about 200 records in the select, I don't want to have a multiselect field because it's not that easy to use.
So I created one of those fancy multiselects similar to the categories field in the add/edit product admin section.
It looks nicer, but I cannot set a default value to it.
Here is my configuration (notice the default config item):

<field name="affected_countries" formElement="select" component="Magento_Ui/js/form/element/ui-select" sortOrder="100">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="source" xsi:type="string">article</item>
            <item name="filterOptions" xsi:type="boolean">true</item>
            <item name="chipsEnabled" xsi:type="boolean">true</item>
            <item name="disableLabel" xsi:type="boolean">true</item>
            <item name="default" xsi:type="string">RO,MD</item>
        </item>
    </argument>
    <settings>
        <elementTmpl>ui/grid/filters/elements/ui-select</elementTmpl>
        <dataType>text</dataType>
        <label translate="true">Affected Countries</label>
        <dataScope>affected_countries</dataScope>
        <componentType>field</componentType>
    </settings>
    <formElements>
        <select>
            <settings>
                <options class="Magento\Config\Model\Config\Source\Locale\Country"/>
            </settings>
        </select>
    </formElements>
</field>

It results into this:

And I'm expecting the 2 values I placed in the default field to be selected:

If I turn the element into a simple multiselect it works nicely.

<field name="affected_countries" formElement="multiselect" sortOrder="100">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="source" xsi:type="string">article</item>
            <item name="default" xsi:type="string">RO,MD</item>
        </item>
    </argument>
    <settings>
        <dataType>text</dataType>
        <label translate="true">Affected Countries</label>
        <dataScope>affected_countries</dataScope>
    </settings>
    <formElements>
        <multiselect>
            <settings>
                <options class="Magento\Config\Model\Config\Source\Locale\Country"/>
            </settings>
        </multiselect>
    </formElements>
</field>

I tied with this format for the default setting

<item name="default" xsi:type="string">RO,MD</item>

and this one also:

<item name="default" xsi:type="array">
    <item name="MD" xsi:type="string">MD</item>
    <item name="RO" xsi:type="string">RO</item>
</item>

Also tried with the tag select and multiselect inside the formElements tag.
All of my tries ended up in failure.

Using the default setting in any other types of fields, as instructed here (text, select, date, …) works nicely.

Any suggestion for the fancy selects? Something I missed?

Note: I know I can supply a default value in the data provider that populates the form, but I'm trying to avoid this as it looks ugly and it's not that extensible and not consistent with the rest of the fields.

Best Answer

I worked for custom categories but in this method you have to provide countries data via database, take idea from this code and you may provide data from Db or Static Data by extending magento data, Hope it may helps

The xml code

    <field name="country_id">
    <argument name="data" xsi:type="array">
        <item name="options" xsi:type="object">Vendor\Module\Model\Config\Source\CountriesTree</item>
        <item name="config" xsi:type="array">
            <item name="label" xsi:type="string" translate="true">Country</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</item>
            <item name="elementTmpl" xsi:type="string">ui/grid/filters/elements/ui-select</item>
            <item name="dataScope" xsi:type="string">category_id</item>
            <item name="filterOptions" xsi:type="boolean">true</item>
            <item name="chipsEnabled" xsi:type="boolean">true</item>
            <item name="showCheckbox" xsi:type="boolean">true</item>
            <item name="disableLabel" xsi:type="boolean">true</item>
            <item name="multiple" xsi:type="boolean">true</item>
            <item name="levelsVisibility" xsi:type="number">1</item>
            <item name="sortOrder" xsi:type="number">30</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">false</item>
            </item>
            <item name="listens" xsi:type="array">
                <item name="index=create_category:responseData" xsi:type="string">setParsed</item>
                <item name="newOption" xsi:type="string">toggleOptionSelected</item>
            </item>
        </item>
    </argument>
</field>

The Cofig Code

<?php

namespace Vendor\Module\Model\Config\Source;

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

protected $_countryCollectionFactory;

protected $_options;

protected $_childs;


public function __construct(
    \Vendor\Module\Model\ResourceModel\Country\CollectionFactory 
 $countryCollectionFactory
) {
    $this->_countryCollectionFactory = $countryCollectionFactory;
}

public function toOptionArray()
{
    if ($this->_options === null) {
        $this->_options = $this->_getOptions();
    }
    return $this->_options;
}

protected function _getOptions($itemId = 0)
{
    $childs =  $this->_getChilds();
    $options = [];

    if (isset($childs[$itemId])) {
        foreach ($childs[$itemId] as $item) {
            $data = [
                'label' => $item->getCountry_title(),
                'value' => $item->getCountry_id(),
            ];

             if (isset($childs[$item->getCountry_id()])) {
                 $data['optgroup'] = $this->_getOptions($item->getCountry_id());
             }

            $options[] = $data;
        }
    }

    return $options;
}

protected function _getChilds()
{
    if ($this->_childs === null) {
        $this->_childs =  $this->_countryCollectionFactory->create()
            ->getGroupedChilds();
    }
    return $this->_childs;
}
}

The output looks like this enter image description here