Magento 2 how to add a grid to the custom tab in customer edit page

Look for the previous block (), for adding tab to magento 2, we will be moving with the layout file of controller we created in our last block.

Create a file with mentioned path view\adminhtml\layout\invoice_index_view.xml and add the following code:-

<layout xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <container name="root" label="Root">
        <block class="W3solver\Invoice\Block\Adminhtml\Customer\Grid\Invoice" name=""/>

Above code provides us the block class which will have our grid details, thus following that class name we will be creating a block file (Block\Adminhtml\Customer\Edit\Tab\Invoice.php)

namespace W3solver\Invoice\Block\Adminhtml\Customer\Grid;

use Magento\Customer\Controller\RegistryConstants;

class Invoice extends \Magento\Backend\Block\Widget\Grid\Extended {

    protected $_coreRegistry = null;
    protected $collectionFactory;
    protected $_customerFactory;

    public function __construct(
    \Magento\Backend\Block\Template\Context $context, \Magento\Backend\Helper\Data $backendHelper, \Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory $collectionFactory, \Magento\Framework\Registry $coreRegistry, \Magento\Customer\Model\CustomerFactory $customerFactory, array $data = []
    ) {
        $this->_coreRegistry = $coreRegistry;
        $this->_collectionFactory = $collectionFactory;
        $this->_customerFactory = $customerFactory;

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

    protected function _construct() {
        $this->setDefaultSort('target_invoive_id', 'desc');

    protected function _prepareCollection() {

        $customer = $this->_customerFactory->create();
        $customer = $customer->load($this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID))->getData();

        $collection = $this->_collectionFactory->getReport('sales_order_invoice_grid_data_source')->addFieldToFilter(
                'customer_email', $customer['email']

        return parent::_prepareCollection();

    protected function _prepareColumns() {

        $this->addColumn('increment_id', ['header' => __('Invoice'), 'width' => '100', 'index' => 'increment_id']);

        $this->addColumn('created_at', ['header' => __('Invoice Date'), 'width' => '100', 'index' => 'created_at', 'type' => 'date']);

        $this->addColumn('order_increment_id', ['header' => __('Order #'), 'width' => '100', 'index' => 'order_increment_id']);

        $this->addColumn('order_created_at', ['header' => __('Order Date'), 'index' => 'order_created_at', 'type' => 'date']);

        $this->addColumn('state', ['header' => __('Status'), 'index' => 'state', 'type' => 'state']);

                'base_grand_total', [
            'header' => __('Grand Total (Base)'),
            'index' => 'base_grand_total',
            'type' => 'currency',
            'currency' => 'base_grand_total'

                'grand_total', [
            'header' => __('Grand Total (Purchased)'),
            'index' => 'interest_amount',
            'type' => 'currency',
            'currency' => 'grand_total'

return parent::_prepareColumns();

    public function formattedStatus($value, $row, $column, $isExport) {

        return ucfirst($value);


So above code will get a collection of invoice through getReport(‘sales_order_invoice_grid_data_source’) function, where if you want collection through some custom source/table then you need to add datasource entry in di.xml and have models created for it respectively.


  1. Followed your tutorial to generate tab and grid.Able to get the tab but on button click get 404 not found error on ajax call.Also have route file for module which has route name and frontname as compare and my get tab url is compared/*/compare and my layout.xml is compared_index_compare.Unable to resolve this issue.


Leave a Comment.