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>
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.
1 Answer 1
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
-
oh...but this question was asked 7 months ago :(sheraz khan– sheraz khan2018年10月29日 13:48:46 +00:00Commented Oct 29, 2018 at 13:48
-
The values come from the db already. I just need on the "Add screen" when I'm not editing something stored in the db to pre select default values. I don't think this solves my problem. Also, I don't need a tree-like structure. I just have a flat list of countries.Marius– Marius2018年10月29日 14:11:13 +00:00Commented Oct 29, 2018 at 14:11
-
Yes we must use default data for this, in my case i write dataprovider but in your case this in not efficient approach, in your case via xml is suitablesheraz khan– sheraz khan2018年10月30日 12:11:48 +00:00Commented Oct 30, 2018 at 12:11
Explore related questions
See similar questions with these tags.
<options class="Magento\Config\Model\Config\Source\Locale\Country"/>. You need a similar class that implements\Magento\Framework\Option\ArrayInterfaceand has a method calledtoOptionArraythat returns an array with your values. each element from the array must look like this['value' => ..., 'label' => ...]