4

I'm trying to show the selected options in a multiselect in a custom admin module form. The data for the multi select field is saved in the database.

What i have as field:

<field name="position_options">
       <argument name="data" xsi:type="array">
           <item name="options" xsi:type="object">{Vendor}\{Module}\Model\Form\Source\OptionsMultiselect</item>
           <item name="config" xsi:type="array">
               <item name="dataType" xsi:type="string">text</item>
               <item name="label" translate="true" xsi:type="string">Positions</item>
               <item name="formElement" xsi:type="string">multiselect</item>
           </item>
       </argument>
   </field>

If i add:

<item name="default" xsi:type="string">0,1,2</item>

Between it will hightlight fields with corresponding id's.

But how do i get the data from the database in there? Or do i need to do it in another way?

Thanks in advance!


<argument name="class" xsi:type="string">{Vendor}\{Module}\Model\DataProvider</argument>



class DataProvider extends AbstractDataProvider
{
    /**
     * @var ResourceModel\Data\Collection
     */
    protected $collection;

    /**
     * @var DataPersistorInterface
     */
    protected $dataPersistor;

    /**
     * @var array
     */
    protected $loadedData;

    /**
     * @param string $name
     * @param string $primaryFieldName
     * @param string $requestFieldName
     * @param CollectionFactory $pageCollectionFactory
     * @param DataPersistorInterface $dataPersistor
     * @param array $meta
     * @param array $data
     */
    public function __construct(
        $name,
        $primaryFieldName,
        $requestFieldName,
        CollectionFactory $pageCollectionFactory,
        DataPersistorInterface $dataPersistor,
        array $meta = [],
        array $data = []
    ) {
        $this->collection    = $pageCollectionFactory->create();
        $this->dataPersistor = $dataPersistor;
        $this->meta           = $this->prepareMeta($this->meta);
        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
    }

    /**
     * Prepares Meta
     *
     * @param array $meta
     * @return array
     */
    public function prepareMeta(array $meta)
    {
        return $meta;
    }

    /**
     * Get data
     *
     * @return array
     */
    public function getData()
    {
        if (isset($this->loadedData)) {
            return $this->loadedData;
        }
        $items = $this->collection->getItems();
        foreach ($items as $page) {
            $this->loadedData[$page->getId()] = $page->getData();
        }
        $data = $this->dataPersistor->get('module_messages');
        if (!empty($data)) {
            $page = $this->collection->getNewEmptyItem();
            $page->setData($data);
            $this->loadedData[$page->getId()] = $page->getData();
            $this->dataPersistor->clear('module_messages');
        }
        return $this->loadedData;
    }
}

Didn't change it in here. Added

 protected function _getLoadSelect($field, $value, $object)
{
    $select = parent::_getLoadSelect($field, $value, $object);

    $select
        ->joinLeft(
            [
                'rel' => $this->getTable('shirtsbedrukken_overprinttable_data_options_rel'),
            ],
            'shirtsbedrukken_overprinttable_data.sod_id = rel.sod_id',
            ['rel.soo_id']
        )
        ->joinLeft(
            [
                'soo' => $this->getTable('shirtsbedrukken_overprinttable_options'),
            ],
            'rel.soo_id = soo.soo_id',
            ['soo_id']
        );
    return $select;
}

Inside \Model\ResourceModel

Was is in the wrong place?

2

This may be not needed now, but for someone else might;

You need to add below function inside

ResourceModel/[YourModelName]/Collection.php.

Ex: in this case it's

vendor/magento/module-cms/Model/ResourceModel/Page/Collection.php.

/**
     * Perform operations after collection load
     *
     * @return $this
     */
    protected function _afterLoad()
    {
        $entityMetadata = $this->metadataPool->getMetadata(PageInterface::class);
        $this->performAfterLoad('cms_page_store', $entityMetadata->getLinkField());
        $this->_previewFlag = false;

        return parent::_afterLoad();
    }

Then you need to add the performAfterLoad function either in the same Collection.php or in its AbstractCollection class.

You can find the function for this example in following file vendor/magento/module-cms/Model/ResourceModel/AbstractCollection.php

Pls change those functions according to your tables.

  • Thanks, it works for me. you can use this when you want to display data of two tables in a single form. – Chirag Patel Aug 23 at 7:25
1

When use multi-select Use the data source to add option to select

<field name="position_options">
       <argument name="data" xsi:type="array">
<item name="options" xsi:type="object">Namespace\ModuleName\Model\Questions\OptionSource</item>
        <item name="config" xsi:type="array">
         .....
        </item>
</argument>
</field>

Ex:

<field name="customer_group_ids">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="label" xsi:type="string">Customer Groups</item>
                    <item name="dataType" xsi:type="string">number</item>
                    <item name="formElement" xsi:type="string">multiselect</item>
                    <item name="validation" xsi:type="array">
                        <item name="required-entry" xsi:type="boolean">true</item>
                    </item>
                    <item name="source" xsi:type="string">catalog_rule</item>
                    <item name="dataScope" xsi:type="string">customer_group_ids</item>
                </item>
                <item name="options" xsi:type="object">Magento\CatalogRule\Model\Rule\CustomerGroupsOptionsProvider</item>
            </argument>
        </field>

PHP Class

 class OptionSource implements OptionSourceInterface
    {
       /**
         * Return array of options as value-label pairs
         *
         * @return array Format: array(array("value" => "<value>", "label"=> "<label>"), ...)
         */
        public function toOptionArray()
        {
            /**
             * @var $questionCollection \Namespace\ModuleName\Model\ResourceModel\Questions\Collection
             */

            $questionCollection = $this->_collectionFactory->create();
            $options = [];
            foreach ($questionCollection as $question) {
                $options[] = [
                    'label' => $question->getTitle(),
                    'value' => $question->getId()
                ];
            }
            return $options;
        }
    }
  • My collectionfactory->create doesn't return my data. if i do $this->collectionfactory->create()->getCollection()->getData(), i can set my values. But still they are not selected after save. – Johan Dec 15 '17 at 8:37
  • i'm looking for how to do multi select, do you have the answer that you want now? please help :) magento.stackexchange.com/questions/238037/… – fudu Aug 14 '18 at 1:51
0

Try to add this code below:

<item name="dataScope" xsi:type="string">attribute</item>

the attribute is your attribute name that your saved in database.

  • Did not work unfortunately. I got it as a second table. With a relation table. In my resource model collection i join the tables with _getLoadSelect() If i dump the query and load it in mysql i get what i want. But i cannot set the options for the multiselect. <item name="dataScope" xsi:type="string">soo.soo_id</item> <item name="dataScope" xsi:type="string">soo_id</item> <item name="dataScope" xsi:type="string">soo.option_name</item> – Johan Dec 14 '17 at 14:42
  • Show me your DataProvider @Johan – Nero Phung Dec 14 '17 at 14:46
  • Added my code as above :) I can see what getData returns, i don't see my option name in there.. – Johan Dec 14 '17 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.