1

Question is very clear. I want to display custom drop-down options which are collection of other custom module in admin form.

I did something like this after @Sohel Rana suggested This question.

form.xml (From 1st module):

<field name="category">
    <argument name="data" xsi:type="array">
        <!-- Call to collection of 2nd module -->
        <item name="options" xsi:type="object">Namespace\Modulename\Block\Item\ItemList</item>
        <item name="config" xsi:type="array">
            <item name="dataType" xsi:type="string">text</item>
            <item name="label" xsi:type="string" translate="true">Category</item>
            <item name="formElement" xsi:type="string">select</item>
            <item name="source" xsi:type="string">mode</item>
            <item name="dataScope" xsi:type="string">category</item>
            <item name="sortOrder" xsi:type="number">30</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">true</item>
            </item>
        </item>
    </argument>
</field>

ItemList.php (From 2nd module):

<?php

namespace Namespace\Modulename\Block\Item;


use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Namespace\Modulename\Model\Item;
use Namespace\Modulename\Model\ResourceModel\Item\CollectionFactory as ItemCollectionFactory;
use Namespace\Modulename\Api\Data\ItemInterface;




class ItemList extends Template
{

    protected $itemCollectionFactory;

    public function __construct(
        Context $context,
        ItemCollectionFactory $itemCollectionFactory,
        array $data = []
    ) {
        $this->itemCollectionFactory = $itemCollectionFactory;

        parent::__construct($context, $data);
    }



    public function getAllOptions()
    {
        if (!$this->_options) {
            $this->_options = $this->itemCollectionFactory->create()->load()->toOptionArray();
            array_unshift($this->_options, ['value' => '', 'label' => __('Please select a category.')]);
        }
        return $this->_options;
    }

    public function toOptionArray()
    {
        return $this->_toOptionArray('id', 'title');
    }

}

I am getting following error on form page of first module.

Warning: array_values() expects parameter 1 to be array, object given in /var/www/magento-2/vendor/magento/module-ui/Component/Form/Element/AbstractOptionsField.php on line 54

#1 /var/www/magento-2/vendor/magento/module-ui/Component/Form/Element/AbstractOptionsField.php(54): array_values(Object(Namespace\Modulename\Block\Item\ItemList))

2

I didn't check this solution, but try to change:

class ItemList extends Template

to the:

class ItemList extends Template implements \Magento\Framework\Data\OptionSourceInterface

Because in the \Magento\Ui\Component\Form\Element\AbstractOptionsField::prepare() method exists the check:

if ($this->options instanceof OptionSourceInterface) {
    $options = $this->options->toOptionArray();
} else {
    $options = array_values($this->options);
}

Make sure that the _toOptionArray method exists in your class Namespace\Modulename\Model\ResourceModel\Item\Collection and it is a Public method (or use the toOptionArray method).

public function toOptionArray()
 {
      return $this->_toOptionArray('id', 'title');
 }

Complete code of your class:

<?php

namespace Namespace\Modulename\Block\Item;

use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Namespace\Modulename\Model\Item;
use Namespace\Modulename\Model\ResourceModel\Item\CollectionFactory as ItemCollectionFactory;
use Namespace\Modulename\Api\Data\ItemInterface;

class ItemList extends Template implements \Magento\Framework\Data\OptionSourceInterface
{

    protected $itemCollectionFactory;

    public function __construct(
        Context $context,
        ItemCollectionFactory $itemCollectionFactory,
        array $data = []
    ) {
        $this->itemCollectionFactory = $itemCollectionFactory;

        parent::__construct($context, $data);
    }

    public function toOptionArray()
    {
        if (!$this->_options) {
            $this->_options = $this->itemCollectionFactory
                ->create()
                ->load()
                ->toOptionArray('id', 'title');
            array_unshift($this->_options, ['value' => '', 'label' => __('Please select a category.')]);
        }

        return $this->_options;
    }

}
  • 1
    Invalid method Namespace\Modulename\Block\Item\ItemList::_toOptionArray should i add anything else? – HungryDB Aug 31 '16 at 8:28
  • @HungryDB see updated answer – Siarhey Uchukhlebau Aug 31 '16 at 8:37
  • Will you rewrite getAllOptions function for me (the one which i mentioned in question)? I don't understand how it will get call to _toOptionArray(). – HungryDB Aug 31 '16 at 8:49
  • @HungryDB I have made changes to your class and have added a code to the answer – Siarhey Uchukhlebau Aug 31 '16 at 8:53
  • 1
    i will edit your answer to add toOptionArray() function which worked for me. Thanks for help. – HungryDB Aug 31 '16 at 9:26

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.