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

1 Answer 1

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

}
7
  • 1
    Invalid method Namespace\Modulename\Block\Item\ItemList::_toOptionArray should i add anything else?
    – HungryDB
    Commented Aug 31, 2016 at 8:28
  • @HungryDB see updated answer Commented Aug 31, 2016 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
    Commented Aug 31, 2016 at 8:49
  • @HungryDB I have made changes to your class and have added a code to the answer Commented Aug 31, 2016 at 8:53
  • 1
    i will edit your answer to add toOptionArray() function which worked for me. Thanks for help.
    – HungryDB
    Commented Aug 31, 2016 at 9:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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