2

I need to create custom tab on admin customer edit page, that has grid table(with search, filters, sortings etc) and also another blocks (template block and custom form). Here is part of layout xml for this tab

 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
 <container name="root" label="Root">
   <block class="VendorName\ModuleName\Block\Adminhtml\Edit\Customer\Tab\View\SomeBlock" name="someblock1" template="VendorName_ModuleName::customer/tab/mytemplate.phtml" />
   <block class="VendorName\ModuleName\Block\Adminhtml\Edit\Customer\Tab\View\MyForm" name="someblock2" />
   <block class="Magento\Backend\Block\Widget\Grid" name="customer.transaction.edit.tab">
        <arguments>
            <argument name="dataSource" xsi:type="object">VendorName\ModuleName\Model\ResourceModel\CustomModel\Collection\Grid</argument>
            <argument name="id" xsi:type="string">Grid</argument>
            <argument name="use_ajax" xsi:type="string">true</argument>
            <argument name="grid_url" xsi:type="url" path="*/*/path-to-this-tab">
                <param name="_current">1</param>
            </argument>
        </arguments>
        <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" as="grid.columnSet" name="customer.edit.tab.columnSet">
.
.
.

So here you see I have two blocks and grid description. It works until you try to interact with grid (sort columns, search etc) because grid uses grid_url argument for ajax requests so it loads whole layout again what causes duplication of other blocks(template and custom form).

Then I created separate layout xml and controller for grid and specify its path in grid_url(in both layouts) This way it works good, but now I have the same piece of xml code to determine the grid that repeats twice in two layouts, which is not good, but I don't know how to solve this problem another way. Maybe you can suggest better solution. Thank you

1 Answer 1

2

Ok, let's start a story. A bunch of files we'll need.

1) Adding new tab in layout file (for example customer_index_edit.xml)

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="customer_form">
            <block class="Amasty\Rewards\Block\Adminhtml\RewardsTab" name="amrewards" />
        </referenceBlock>
    </body>
</page>

2) Creating tab class

Amasty/Rewards/Block/Adminhtml/RewardsTab.php

which's main part of code is:

public function getTabUrl()
{
    return $this->getUrl('amasty_rewards/rewards/index/', ['_current' => true]);
}

3) Creating new layout file amasty_rewards_rewards_index.xml where we'll specify blocks and grid:

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <update handle="amasty_rewards_rewards_ajaxgrid" />
    <container name="root">
        <block class="Amasty\Rewards\Block\Adminhtml\Edit\Tab\View\PersonalInfo" name="personal_info" template="Amasty_Rewards::tab/view/personal_info.phtml"/>
        <block class="Amasty\Rewards\Block\Adminhtml\Rewards\Edit\NewReward" name="add-points" template="Amasty_Rewards::rewards/edit/new/form.phtml"/>
    </container>
</layout>

4) Creating grid layout file amasty_rewards_rewards_grid.xml:

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <update handle="amasty_rewards_rewards_ajaxgrid"/>
    <container name="root">
    </container>
</layout>

5) And another one amasty_rewards_rewards_ajaxgrid.xml:

<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <referenceContainer name="root">
        <block class="\Magento\Backend\Block\Widget\Grid" after="add-points" name="customer.rewards.edit.tab">
            <arguments>
                <argument name="dataSource" xsi:type="object">Amasty\Rewards\Model\ResourceModel\Rewards\Collection\Grid</argument>
                <argument name="id" xsi:type="string">rewardsGrid</argument>
                <argument name="use_ajax" xsi:type="string">true</argument>
                <argument name="default_sort" xsi:type="string">id</argument>
                <argument name="grid_url" xsi:type="url" path="*/*/grid">
                    <param name="_current">1</param>
                </argument>
                <argument name="product_configuration_helpers" xsi:type="array">
                    <item name="default" xsi:type="string">Magento\Catalog\Helper\Product\Configuration</item>
                </argument>
            </arguments>
            <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" as="grid.columnSet" name="customer.rewards.edit.tab.columnSet">
                <arguments>
                    <argument name="empty_text" xsi:type="string" translate="true">No Items Found</argument>
                </arguments>

                <block class="Magento\Backend\Block\Widget\Grid\Column" as="action_date">
                    <arguments>
                        <argument name="header" xsi:type="string" translate="true">Date</argument>
                        <argument name="index" xsi:type="string">action_date</argument>
                        <argument name="gmtoffset" xsi:type="string">1</argument>
                        <argument name="type" xsi:type="string">date</argument>
                        <argument name="id" xsi:type="string">action_date</argument>
                    </arguments>
                </block>
...

We're done with layouts. Now we need Controllers.

6) Grid controller

app/code/Amasty/Rewards/Controller/Adminhtml/Rewards/Grid.php

<?php

namespace Amasty\Rewards\Controller\Adminhtml\Rewards;

class Grid extends \Amasty\Rewards\Controller\Adminhtml\Rewards
{
    public function execute()
    {
        $this->initCurrentCustomer();
        $this->_view->loadLayout();
        $this->_view->renderLayout();
    }
}

7) And index controller

app/code/Amasty/Rewards/Controller/Adminhtml/Rewards/Index.php

<?php

namespace Amasty\Rewards\Controller\Adminhtml\Rewards;

class Index extends \Amasty\Rewards\Controller\Adminhtml\Rewards
{

    public function execute()
    {
        $customerId = $this->initCurrentCustomer();

        $model = $this->_objectManager->create('Amasty\Rewards\Model\Rewards');
        $statistic = $model->getStatistic($customerId);

        $this->_coreRegistry->register('current_amasty_rewards_statistic', $statistic);

        $resultLayout = $this->resultLayoutFactory->create();
        return $resultLayout;
    }
}

And finally here is the result: enter image description here

1
  • what about mention the location for the files in your answer.So it will be great help for the reader right?
    – Mujahidh
    Commented Oct 3, 2017 at 8:47

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.