1

I've created a model management pages in admin by UI Component. When saving this model, the controller will save the user id of creator to the table then show this on the model listing page. It is simple to achieve:

<column name="creator_id">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="filter" xsi:type="string">text</item>
            <item name="label" xsi:type="string" translate="true">Creator Id</item>
        </item>
    </argument>
</column>

But, user id is difficult to distinguish. So, now I want to transform the creator ID to the user Name, how to achieve that?

Notice the model table has the user_id column, but doesn't have the user_name. The UI Component need to use the user_id to get user_name, then put the name in the listing page.

5
  • Have you solved this? Dec 10, 2019 at 9:09
  • @DhadukMitesh Yes, see my answer below.
    – Key Shang
    Dec 10, 2019 at 9:27
  • Yes but it is not working in filter. Any idea? Dec 10, 2019 at 9:29
  • @DhadukMitesh See solution 2 in my answer - join table in collection
    – Key Shang
    Dec 11, 2019 at 2:56
  • I used _renderFiltersBefore method. Dec 11, 2019 at 6:09

1 Answer 1

5

Solution 2(better, can filter): join table in collection

In the Vendor\Module\Model\ResourceModel\ModelName\Collection, add the _initSelect() function like below

protected function _initSelect()
{
    parent::_initSelect();

    $this->getSelect()->joinLeft(
        ['secondTable' => $this->getTable('admin_user')],
        'main_table.creator_id = secondTable.user_id',
        ['username']
    );
}

If you want to join more tables or know more details about join tables, you could see my another answer join multiple table in collection which build Admin Grid


In the UI Componet, add the username column

<column name="username">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="filter" xsi:type="string">text</item>
            <item name="label" xsi:type="string" translate="true">User Name</item>
        </item>
    </argument>
</column>

I think this is a better solution than solution 1. Because you could use the username column to filter collection.


Solution 1(cannot filter): add class in UI Componet

In the UI Componet, add class for the creator_id:

<column name="creator_id"  class="Vendor\Module\Ui\Component\Listing\Column\CreatorName">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="filter" xsi:type="string">text</item>
            <item name="label" xsi:type="string" translate="true">Creator Id</item>
        </item>
    </argument>
</column>

Create the class Vendor\Module\Ui\Component\Listing\Column\CreatorName, add the user name in the public function prepareDataSource(array $dataSource). Whole codes is shown below:

<?php
namespace Vendor\Module\Ui\Component\Listing\Column;

use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\User\Model\UserFactory;

class CreatorName extends Column
{
    protected $userFactory;

    /**
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param array $components
     * @param array $data
     * @param UserFactory $userFactory
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        array $components = [],
        array $data = [],
        UserFactory $userFactory
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
        $this->userFactory = $userFactory;
    }

    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     * @return array
     */
    public function prepareDataSource(array $dataSource)
    {
        if (isset($dataSource['data']['items'])) {
            $fieldName = $this->getData('name');
            foreach ($dataSource['data']['items'] as & $item) {
                if ($item[$fieldName] != '') {
                    $adminName = $this->getAdminName($item[$fieldName]);
                    $item[$fieldName] = $item[$fieldName].' ('.$adminName.')';
                }
            }
        }
        return $dataSource;
    }

    /**
     * @param $userId
     * @return string
     */
    private function getAdminName($userId)
    {
        $user = $this->userFactory->create()->load($userId);
        $name = $user->getName();
        return $name;
    }
}
1
  • 2 solution is working but as said filters are not working but i tried 1 one but stll data is not fetching $this->getSelect()->joinLeft( ['secondTable' => $this->getTable('customer_entity')], 'main_table.customer_id = secondTable.entity_id', ['firstname'] Nov 8, 2021 at 13:40

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.