I want to add customer grid in custom module's tab in Magento 2.1 How can I achieve this?
1 Answer 1
Follow Step to add the customer grid in tab.
app/code/VendorName/ModuleName/Block/Adminhtml/Customer/Tabs.php
<?php
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
namespace VendorName\ModuleName\Block\Adminhtml\Customer\Edit;
class Tabs extends \Magento\Backend\Block\Widget\Tabs
{
 /**
 * @return void
 */
 protected function _construct()
 {
 parent::_construct();
 $this->setId('page_tabs');
 $this->setDestElementId('edit_form');
 $this->setTitle(__('Notification Information'));
 }
 protected function _beforeToHtml()
 { 
 $this->addTab('customergrid', array(
 'label' => __('Customers'),
 'title' => __('Customers'),
 'content' => $this->getLayout()->createBlock('JT\PushNotification\Block\Adminhtml\Notification\Edit\Tab\Customers')->toHtml(),
 ));
 return parent::_beforeToHtml();
 }
}
app/code/VendorName/ModuleName/Block/Adminhtml/Customer/Edit/Tab/Customers.php
<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace VendorName\ModuleName\Block\Adminhtml\Customer\Edit\Tab;
class Customers extends \Magento\Backend\Block\Template
{
 /**
 * Block template
 *
 * @var string
 */
 protected $_template = 'customer/customers.phtml';
 /**
 * @var \Magento\Catalog\Block\Adminhtml\Category\Tab\Product
 */
 protected $blockGrid;
 /**
 * @var \Magento\Framework\Registry
 */
 protected $registry;
 /**
 * @var \Magento\Framework\Json\EncoderInterface
 */
 protected $jsonEncoder;
 /**
 * AssignProducts constructor.
 *
 * @param \Magento\Backend\Block\Template\Context $context
 * @param \Magento\Framework\Registry $registry
 * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
 * @param array $data
 */
 public function __construct(
 \Magento\Backend\Block\Template\Context $context,
 \Magento\Framework\Registry $registry,
 \Magento\Framework\Json\EncoderInterface $jsonEncoder,
 array $data = []
 ) {
 $this->registry = $registry;
 $this->jsonEncoder = $jsonEncoder;
 parent::__construct($context, $data);
 }
 /**
 * Retrieve instance of grid block
 *
 * @return \Magento\Framework\View\Element\BlockInterface
 * @throws \Magento\Framework\Exception\LocalizedException
 */
 public function getBlockGrid()
 {
 if (null === $this->blockGrid) {
 $this->blockGrid = $this->getLayout()->createBlock(
 'VendorName\ModduleName\Block\Adminhtml\Customer\Edit\Tab\CustomerGrid',
 'customer.grid'
 );
 }
 return $this->blockGrid;
 }
 /**
 * Return HTML of grid block
 *
 * @return string
 */
 public function getGridHtml()
 {
 return $this->getBlockGrid()->toHtml();
 }
 /**
 * @return string
 */
 public function getCustomersJson()
 {
 $notificationId = $this->getRequest()->getParam('notification_id', false);
 $customers = [];
 if($notificationId) {
 $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
 $collection = $objectManager->create('VendorName\ModuleName\Model\NotificationQueue')->getCollection();
 $collection->addFieldToFilter('notification_id', ['eq' => $notificationId]);
 if ( $collection->getSize() > 0 ) {
 foreach ($collection as $notification) {
 $customers[$notification->getCustomerId()] = '';
 }
 }
 }
 if (!empty($customers)) {
 return $this->jsonEncoder->encode($customers);
 }
 return '{}';
 }
}
app/code/VendorName/ModuleName/Block/Adminhtml/Customer/Edit/Tab/CustomerGrid.php
<?php
namespace VendorName\ModuleName\Block\Adminhtml\Customer\Edit\Tab;
/**
 * Class Porders
 * @package VendorName\ModuleName\Block\Adminhtml\Customer\Edit\Tab
 */
class CustomerGrid extends \Magento\Backend\Block\Widget\Grid\Extended
{
 /**
 * @var \Magento\Framework\Registry
 */
 protected $registry;
 protected $_objectManager = null;
 /**
 *
 * @param \Magento\Backend\Block\Template\Context $context
 * @param \Magento\Backend\Helper\Data $backendHelper
 * @param \Magento\Framework\Registry $registry
 * @param \Magento\Framework\ObjectManagerInterface $objectManager
 * @param \Magento\Customer\Model\Customer $customerCollection,
 * @param array $data
 */
 public function __construct(
 \Magento\Backend\Block\Template\Context $context,
 \Magento\Backend\Helper\Data $backendHelper,
 \Magento\Framework\Registry $registry,
 \Magento\Framework\ObjectManagerInterface $objectManager,
 \Magento\Customer\Model\Customer $customerCollection
 array $data = []
 ) {
 $this->customerCollection = $customerCollection;
 $this->_objectManager = $objectManager;
 $this->registry = $registry;
 parent::__construct($context, $backendHelper, $data);
 }
 /**
 * _construct
 * @return void
 */
 protected function _construct()
 {
 parent::_construct();
 $notificationId = $this->getRequest()->getParam('notification_id',0);
 $this->setId('customerGrids_'.$notificationId);
 $this->setDefaultSort('entity_id');
 $this->setSaveParametersInSession(true);
 $this->setUseAjax(true);
 }
 /**
 * add Column Filter To Collection
 */
 protected function _addColumnFilterToCollection($column)
 {
 if ($column->getId() == 'in_customer') {
 $productIds = $this->_getSelectedCustomers();
 if (empty($productIds)) {
 $productIds = 0;
 }
 if ($column->getFilter()->getValue()) {
 $this->getCollection()->addFieldToFilter('entity_id', array('in' => $productIds));
 } else {
 if ($productIds) {
 $this->getCollection()->addFieldToFilter('entity_id', array('nin' => $productIds));
 }
 }
 } else {
 parent::_addColumnFilterToCollection($column);
 }
 return $this;
 }
 /**
 * prepare collection
 */
 protected function _prepareCollection()
 {
 $collection = $this->customerCollection->getCollection();
 $collection->setOrder('entity_id','DESC');
 $this->setCollection($collection);
 return parent::_prepareCollection();
 }
 /**
 * @return $this
 */
 protected function _prepareColumns()
 {
 $this->addColumn(
 'in_customer',
 [
 'header_css_class' => 'a-center',
 'type' => 'checkbox',
 'name' => 'in_customer',
 'align' => 'center',
 'index' => 'entity_id',
 'values' => $this->_getSelectedCustomers(),
 ]
 );
 $this->addColumn(
 'firstname',
 [
 'header' => __('Firstname'),
 'index' => 'firstname',
 'header_css_class' => 'col-id',
 'column_css_class' => 'col-id',
 ]
 );
 $this->addColumn(
 'lastname',
 [
 'header' => __('Lastname'),
 'index' => 'lastname',
 'header_css_class' => 'col-id',
 'column_css_class' => 'col-id',
 ]
 );
 $this->addColumn(
 'email',
 [
 'header' => __('Email'),
 'index' => 'email',
 'header_css_class' => 'col-id',
 'column_css_class' => 'col-id',
 ]
 );
 return parent::_prepareColumns();
 }
 
 /**
 * @return string
 */
 public function getGridUrl()
 {
 return $this->getUrl('notification/index/customergrid', ['_current' => true]);
 }
 /**
 * @param object $row
 * @return string
 */
 public function getRowUrl($row)
 {
 return '';
 }
 protected function _getSelectedCustomers()
 {
 return $this->getCustomerIds();
 }
 protected function getCustomerIds()
 {
 $notificationId = $this->getRequest()->getParam('notification_id', false);
 $customers = [];
 if($notificationId) {
 $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
 $collection = $objectManager->create('VendorName\ModuleName\Model\NotificationQueue')->getCollection();
 $collection->addFieldToFilter('notification_id', ['eq' => $notificationId]);
 if ( $collection->getSize() > 0 ) {
 foreach ($collection as $notification) { 
 $customers[] = $notification->getCustomerId();
 }
 }
 }
 return $customers;
 }
 /**
 * @return $this
 */
 protected function _prepareMassaction()
 {
 return $this;
 }
 /**
 * {@inheritdoc}
 */
 public function canShowTab()
 {
 return true;
 }
 /**
 * {@inheritdoc}
 */
 public function isHidden()
 {
 return true;
 }
}
app/code/VendorName/ModuleName/Controller/Adminhtml/Index/CustomerGrid.php
<?php
namespace VendorName\ModuleName\Controller\Adminhtml\Index;
use Magento\Backend\App\Action;
use Magento\TestFramework\ErrorLog\Logger;
class CustomerGrid extends \Magento\Backend\App\Action
{
 /**
 * @var \Magento\Framework\View\Result\LayoutFactory
 */
 protected $_resultLayoutFactory;
 /**
 * @param \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory
 * @param Action\Context $context
 */
 public function __construct(
 Action\Context $context,
 \Magento\Framework\View\Result\LayoutFactory $resultLayoutFactory
 ) {
 parent::__construct($context);
 $this->_resultLayoutFactory = $resultLayoutFactory;
 }
 /**
 * {@inheritdoc}
 */
 protected function _isAllowed()
 {
 return true;
 }
 /**
 * Save action
 *
 * @return \Magento\Framework\Controller\ResultInterface
 */
 public function execute()
 {
 $resultLayout = $this->_resultLayoutFactory->create();
 $resultLayout->getLayout()->getBlock('VendorName\ModuleName\Block\Adminhtml\Customer\Edit\Tab\Customers');
 return $resultLayout;
 }
}
app/code/VendorName/ModuleName/view/adminhtml/templates/customer/customers.phtml
<?php
$blockGrid = $block->getBlockGrid();
$gridJsObjectName = $blockGrid->getJsObjectName();
?>
<?php echo $block->getGridHtml(); ?>
<input type="hidden" name="notification_customers" id="in_customers" data-form-part="edit_form" value="" />
<script type="text/x-magento-init">
 {
 "*": {
 "VendorName_ModuleName/js/customer/customers": {
 "selectedCustomers": <?php /* @escapeNotVerified */ echo $block->getCustomersJson(); ?>,
 "gridJsObjectName": <?php /* @escapeNotVerified */ echo '"' . $gridJsObjectName . '"' ?: '{}'; ?>
 }
 }
 }
</script>
<!-- @todo remove when "UI components" will support such initialization -->
<script>
 require('mage/apply/main').apply();
</script>
app/code/VendorName/ModuleName/view/adminhtml/layout/notification_index_customergrid.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">
 <container name="root">
 <block class="VendorName\ModuleName\Block\Adminhtml\Customer\Edit\Tab\CustomerGrid" name="notification.customers.grid"/>
 </container>
</layout>
app/code/VendorName/ModuleName/view/adminhtml/web/js/customer/customers.js
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
/* global ,ドル $H */
define([
 'mage/adminhtml/grid'
], function () {
 'use strict';
 return function (config) {
 var selectedCustomers = config.selectedCustomers,
 notificationCustomers = $H(selectedCustomers),
 gridJsObject = window[config.gridJsObjectName],
 tabIndex = 1000;
 $('in_customers').value = Object.toJSON(notificationCustomers);
 /**
 * Register Category Product
 *
 * @param {Object} grid
 * @param {Object} element
 * @param {Boolean} checked
 */
 function registerCategoryProduct(grid, element, checked) {
 if (checked) {
 if (element.positionElement) {
 element.positionElement.disabled = false;
 notificationCustomers.set(element.value, element.positionElement.value);
 }
 notificationCustomers.set(element.value, '');
 } else {
 if (element.positionElement) {
 element.positionElement.disabled = true;
 }
 notificationCustomers.unset(element.value);
 }
 $('in_customers').value = Object.toJSON(notificationCustomers);
 grid.reloadParams = {
 'selected_products[]': notificationCustomers.keys()
 };
 }
 /**
 * Click on product row
 *
 * @param {Object} grid
 * @param {String} event
 */
 function categoryProductRowClick(grid, event) {
 var trElement = Event.findElement(event, 'tr'),
 isInput = Event.element(event).tagName === 'INPUT',
 checked = false,
 checkbox = null;
 if (trElement) {
 checkbox = Element.getElementsBySelector(trElement, 'input');
 if (checkbox[0]) {
 checked = isInput ? checkbox[0].checked : !checkbox[0].checked;
 gridJsObject.setCheckboxChecked(checkbox[0], checked);
 }
 }
 }
 /**
 * Change product position
 *
 * @param {String} event
 */
 function positionChange(event) {
 var element = Event.element(event);
 if (element && element.checkboxElement && element.checkboxElement.checked) {
 notificationCustomers.set(element.checkboxElement.value, element.value);
 $('in_customers').value = Object.toJSON(notificationCustomers);
 }
 }
 /**
 * Initialize category product row
 *
 * @param {Object} grid
 * @param {String} row
 */
 function categoryProductRowInit(grid, row) {
 var checkbox = $(row).getElementsByClassName('checkbox')[0],
 position = $(row).getElementsByClassName('input-text')[0];
 if (checkbox && position) {
 checkbox.positionElement = position;
 position.checkboxElement = checkbox;
 position.disabled = !checkbox.checked;
 position.tabIndex = tabIndex++;
 Event.observe(position, 'keyup', positionChange);
 }
 }
 gridJsObject.rowClickCallback = categoryProductRowClick;
 gridJsObject.initRowCallback = categoryProductRowInit;
 gridJsObject.checkboxCheckCallback = registerCategoryProduct;
 if (gridJsObject.rows) {
 gridJsObject.rows.each(function (row) {
 categoryProductRowInit(gridJsObject, row);
 });
 }
 };
});
After doing all above things run all commands once and check.
Please let me still if you get any error.
Thanks.