Magento 2 – How to Add Custom Column to Customer Admin Grid

admingridmagento2uicomponent

In my module I have custom db table that connected with magento customers by customer_id field.
What I need is to add field value from this table to customer admin grid.
How can I add join with my table and add my column value to customer grid collection, so it looks like other native grid fields with ability to sorting and filtering ?

Best Answer

I resolved it this way

Vendor\Module\view\adminhtml\ui_component\customer_listing.xml:

<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
 <columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
    <column name="my_custom_column">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">My Custom Column</item>
                <item name="sortOrder" xsi:type="number">35</item>
                <item name="filter" xsi:type="string">text</item>
                <item name="sortable" xsi:type="boolean">true</item>
            </item>
        </argument>
    </column>
  </columns>
</listing>

Vendor\Module\etc\di.xml:

<preference for="Magento\Customer\Model\ResourceModel\Grid\Collection"
            type="Magento\Customer\Model\ResourceModel\Grid\Collection2" />
<virtualType name="Magento\Customer\Model\ResourceModel\Grid\Collection2" type="Vendor\Module\Ui\Component\Listing\CustomerDataProvider">
    <arguments>
        <argument name="mainTable" xsi:type="string">customer_grid_flat</argument>
        <argument name="resourceModel" xsi:type="string">Magento\Customer\Model\ResourceModel\Customer</argument>
    </arguments>
</virtualType>

Vendor\Module\Ui\Component\Listing\CustomerDataProvider.php:

class CustomerDataProvider extends \Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult
{
   protected function _initSelect()
   {
      parent::_initSelect();
      $this->getSelect()->joinLeft(
        ['secondTable' => $this->getTable('custom_table')],
        'main_table.entity_id = secondTable.customer_id',
        ['my_custom_column']
      );
      return $this;
  }
}