Définir les valeurs par défaut pour un composant d'interface utilisateur multisélection

13

J'ai une entité personnalisée dans mon installation de magento 2.
Et l'un des champs de cette entité est de type multisélection et contient la liste de tous les pays.
J'utilise les composants ui pour mon formulaire d'administration.
Puisqu'il y a environ 200 enregistrements dans la sélection, je ne veux pas avoir un champ multisélection car ce n'est pas si facile à utiliser.
J'ai donc créé une de ces multisélection fantaisistes similaires au champ des catégories dans la section d'administration du produit.
Il semble plus joli, mais je ne peux pas lui attribuer de valeur par défaut.
Voici ma configuration (notez l' defaultélément de configuration):

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

Il en résulte:

Et je m'attends à ce que les 2 valeurs que j'ai placées dans le champ par défaut soient sélectionnées:

Si je transforme l'élément en une simple sélection multiple, cela fonctionne bien.

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

J'ai attaché avec ce format pour le defaultréglage

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

et celui-ci aussi:

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

A également essayé avec la balise selectet multiselectà l'intérieur de la formElementsbalise.
Tous mes essais ont échoué.

L'utilisation du defaultparamètre dans tout autre type de champs, comme indiqué ici (texte, sélection, date, ...) fonctionne bien.

Une suggestion pour les sélections de fantaisie? Quelque chose que j'ai raté?

Remarque: je sais que je peux fournir une valeur par défaut dans le fournisseur de données qui remplit le formulaire, mais j'essaie d'éviter cela car il semble laid et ce n'est pas extensible et pas cohérent avec le reste des champs.

Marius
la source
avez-vous essayé avec l'id des options?
Adrian Z.29
MD et RO sont les identifiants des options. Comme je l'ai dit, cela fonctionne avec une sélection multiple normale en utilisant les mêmes valeurs par défaut
Marius
<items name = "default" xsi: type = "array"> </items>
Idham Choudry
@IdhamChoudry J'ai déjà essayé ça. C'est ce qui est dit dans la question.
Marius
1
@LazyCoder jetez un oeil dans ma question à ce sujet <options class="Magento\Config\Model\Config\Source\Locale\Country"/>. Vous avez besoin d'une classe similaire qui implémente \Magento\Framework\Option\ArrayInterfaceet possède une méthode appelée toOptionArrayqui renvoie un tableau avec vos valeurs. chaque élément du tableau doit ressembler à ceci['value' => ..., 'label' => ...]
Marius

Réponses:

1

J'ai travaillé pour des catégories personnalisées, mais dans cette méthode, vous devez fournir des données sur les pays via la base de données, prendre une idée à partir de ce code et vous pouvez fournir des données à partir de Db ou de données statiques en étendant les données magento, j'espère que cela peut aider

Le code xml

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

Le code Cofig

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

La sortie ressemble à ceci entrez la description de l'image ici

sheraz khan
la source
oh ... mais cette question a été posée il y a 7 mois :(
sheraz khan
Les valeurs proviennent déjà de la base de données. J'ai juste besoin sur "Ajouter un écran" lorsque je ne modifie pas quelque chose stocké dans la base de données pour présélectionner les valeurs par défaut. Je ne pense pas que cela résout mon problème. De plus, je n'ai pas besoin d'une structure arborescente. J'ai juste une liste plate de pays.
Marius
Oui, nous devons utiliser les données par défaut pour cela, dans mon cas, j'écris dataprovider mais dans votre cas, cette approche n'est pas efficace, dans votre cas via xml convient
sheraz khan