I'm trying to make an grid in customer, but I can't get the post of this grid.
What's is wrong?
Here is my config xml
\Vendor\Rep\view\adminhtml\layout
customer_index_edit.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left"
xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="customer_form">
<block class="Vendor\Rep\Block\Adminhtml\Customer\Edit\Tab\Rep" name="customer_edit_tab_rep">
<action method="setTabLabel">
<argument name="label" xsi:type="string">Sales Representative</argument>
</action>
</block>
</referenceBlock>
</body>
vendor_rep_customer_rep.xml
<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
<container name="root" label="Root">
<block class="Vendor\Rep\Block\Adminhtml\Customer\Edit\Tab\Rep\Grid" name="customer.edit.tab.rep.grid"/>
<block class="Magento\Backend\Block\Widget\Grid\Serializer" name="related_grid_serializer">
<arguments>
<argument name="grid_block" xsi:type="string">customer.edit.tab.rep.grid</argument>
<argument name="callback" xsi:type="string">getSelectedReps</argument>
<argument name="input_element_name" xsi:type="string">reps_ids</argument>
<argument name="reload_param_name" xsi:type="string">reps</argument>
</arguments>
</block>
</container>
Here is my tab and grid classes
\Vendor\Rep\Block\Adminhtml\Customer\Edit\Tab\Rep.php
namespace Vendor\Rep\Block\Adminhtml\Customer\Edit\Tab;
use Magento\Customer\Controller\RegistryConstants;
use Magento\Ui\Component\Layout\Tabs\TabInterface;
/**
* Customer account form block
*/
class Rep extends \Magento\Backend\Block\Template implements TabInterface
{
/**
* Core registry
*
* @var \Magento\Framework\Registry
*/
protected $_coreRegistry;
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Framework\Registry $registry
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Framework\Registry $registry,
array $data = []
) {
$this->_coreRegistry = $registry;
parent::__construct($context, $data);
}
/**
* @return string|null
*/
public function getCustomerId()
{
return $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
}
/**
* @return \Magento\Framework\Phrase
*/
public function getTabLabel()
{
return __('Sales Representative');
}
/**
* @return \Magento\Framework\Phrase
*/
public function getTabTitle()
{
return __('Sales Representative');
}
/**
* @return bool
*/
public function canShowTab()
{
if ($this->getCustomerId()) {
return true;
}
return false;
}
/**
* @return bool
*/
public function isHidden()
{
if ($this->getCustomerId()) {
return false;
}
return true;
}
/**
* Tab class getter
*
* @return string
*/
public function getTabClass()
{
return '';
}
/**
* Return URL link to Tab content
*
* @return string
*/
public function getTabUrl()
{
return $this->getUrl('vendor_rep/customer/rep', ['_current' => true]);
}
/**
* Tab should be loaded trough Ajax call
*
* @return bool
*/
public function isAjaxLoaded()
{
return false;
}
}
\Vendor\Rep\Block\Adminhtml\Customer\Edit\Tab\Rep\Grid.php
namespace Vendor\Rep\Block\Adminhtml\Customer\Edit\Tab\Rep;
use Magento\Customer\Controller\RegistryConstants;
/**
* Adminhtml customer recent orders grid block
*/
class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
{
/**
* @var \Magento\Customer\Model\Customer
*/
protected $_customer = null;
/**
* @var \Magento\Customer\Model\CustomerFactory
*/
protected $_customerFactory = null;
/**
* Core registry
*
* @var \Magento\Framework\Registry|null
*/
protected $_coreRegistry = null;
/**
* @var \Vendor\Rep\Model\Resource\Rep\CollectionFactory
*/
protected $_repCollectionFactory;
/**
* @var \Vendor\Rep\Helper\Customer
*/
protected $_customerHelper;
/**
* Constructor
*
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Framework\Registry $coreRegistry
* @param \Magento\Customer\Model\CustomerFactory $customerFactory
* @param \Magento\Backend\Helper\Data $backendHelper
* @param \Vendor\Rep\Model\Resource\Rep\CollectionFactory $repCollectionFactory
* @param \Vendor\Rep\Helper\Customer $customerHelper
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Framework\Registry $coreRegistry,
\Magento\Backend\Helper\Data $backendHelper,
\Magento\Customer\Model\CustomerFactory $customerFactory,
\Vendor\Rep\Model\Resource\Rep\CollectionFactory $repCollectionFactory,
\Vendor\Rep\Helper\Customer $customerHelper,
array $data = []
) {
$this->_coreRegistry = $coreRegistry;
$this->_repCollectionFactory = $repCollectionFactory;
$this->_customerHelper = $customerHelper;
$this->_customerFactory = $customerFactory;
parent::__construct($context, $backendHelper, $data);
}
/**
* Initialize the grid.
*
* @return void
*/
protected function _construct()
{
parent::_construct();
$this->setId('customer_edit_tab_rep_grid');
$this->setDefaultSort('name');
$this->setDefaultDir('asc');
$this->setUseAjax(true);
/*if ($this->getCustomer() && $this->getCustomer()->getId()) {
$this->setDefaultFilter(['in_reps' => 1]);
}*/
}
/**
* Retrieve currently edited product model
*
* @return array|null
*/
public function getCustomer()
{
if (!$this->_customer || !$this->_customer->getId()) {
$this->_customer = $this->_customerFactory->create()->load($this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID));
}
return $this->_customer;
}
/**
* Add filter
*
* @param Column $column
* @return $this
*/
protected function _addColumnFilterToCollection($column)
{
// Set custom filter for in product flag
if ($column->getId() == 'in_reps') {
$repIds = $this->_getSelectedReps();
if (empty($repIds)) {
$repIds = 0;
}
if ($column->getFilter()->getValue()) {
$this->getCollection()->addFieldToFilter('main_table.rep_id', ['in' => $repIds]);
} else {
if ($repIds) {
$this->getCollection()->addFieldToFilter('main_table.rep_id', ['nin' => $repIds]);
}
}
} else {
parent::_addColumnFilterToCollection($column);
}
return $this;
}
/**
* {@inheritdoc}
*/
protected function _prepareCollection()
{
$collection = $this->_repCollectionFactory->create();
if ($this->getCustomer()->getId()) {
$constraint = 'related.customer_id='.$this->getCustomer()->getId();
} else {
$constraint = 'related.customer_id=0';
}
$collection->getSelect()->joinLeft(
array('related' => $collection->getTable('vendor_rep_customer')),
'related.rep_id=main_table.rep_id AND '.$constraint,
array('position')
);
$this->setCollection($collection);
return parent::_prepareCollection();
}
/**
* {@inheritdoc}
*/
protected function _prepareColumns()
{
$this->addColumn(
'in_reps',
[
'type' => 'checkbox',
'name' => 'in_reps',
'values' => $this->_getSelectedReps(),
'align' => 'center',
'index' => 'rep_id',
'header_css_class' => 'col-select',
'column_css_class' => 'col-select'
]
);
$this->addColumn(
'rep_id',
[
'header' => __('ID'),
'sortable' => true,
'index' => 'rep_id',
'header_css_class' => 'col-id',
'column_css_class' => 'col-id'
]
);
$this->addColumn(
'name',
[
'header' => __('Name'),
'index' => 'name',
'header_css_class' => 'col-name',
'column_css_class' => 'col-name'
]
);
return parent::_prepareColumns();
}
/**
* Retrieve selected related reps
*
* @return array
*/
protected function _getSelectedReps()
{
$reps = $this->getCustomerReps();
if (!is_array($reps)) {
$reps = array_keys($this->getSelectedReps());
}
return $reps;
}
/**
* Retrieve related reps
*
* @return array
*/
public function getSelectedReps()
{
$reps = [];
$selected = $this->_customerHelper->getSelectedReps($this->getCustomer());
if (!is_array($selected)) {
$selected = [];
}
foreach ($selected as $rep) {
//$salesreps[$salesrep->getId()] = array('position' => $salesrep->getPosition());
$reps[$rep->getId()] = array('position' => 0);
}
return $reps;
}
/**
* Rerieve grid URL
*
* @return string
*/
public function getGridUrl()
{
return $this->getData(
'grid_url'
) ? $this->getData(
'grid_url'
) : $this->getUrl(
'vendor_rep/customer/rep',
['_current' => true]
);
}
}
Here is my event
\Vendor\Rep\etc\adminhtml\events.xml
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
<event name="adminhtml_customer_save_after">
<observer name="vendor_rep_save_customer_reps" instance="Vendor\Rep\Observer\SaveCustomerReps" />
</event>
</config>
And here I have an var_dump only to test the post.
\Vendor\Rep\Observer\SaveCustomerReps.php
namespace Vendor\Rep\Observer;
use Magento\Framework\Event\ObserverInterface;
class SaveCustomerReps implements ObserverInterface
{
/**
* Catalog data
*
* @var \Magento\Catalog\Helper\Data
*/
protected $catalogData;
/**
* @param \Magento\Catalog\Helper\Data $catalogData
*/
public function __construct(
\Magento\Framework\App\ResourceConnection $resource
)
{
$this->_resource = $resource;
}
/**
* Checking whether the using static urls in WYSIWYG allowed event
*
* @param \Magento\Framework\Event\Observer $observer
* @return void
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
var_dump($_POST);
}
}
Best Answer
There can be 2 possible problems:
First please make sure if your grid values are populated correctly: if you inspect HTML source below your grid, you should have hidden input with names that represent your config XML input field (in your case it should be like:
<input type="hidden" name="reps_ids" value="" id="id_SOME_GENERATED_VALUE_HERE">
.First of all, make sure when you select something on the grid -> this field should be modified, and value should be updated. If data is not populated, make sure that your grid config is correct.
If the first problem is solved (or does not exists) and values are in hidden field, but are not sent with post, the problem is probably because your grid is not registered as a part of
customer_form
(it is not declared insidecustomer_form.xml
). If you will take a look insideform.js
to see how Magento handle the form you will see something here:There is a selector for additional fields that can be taken into the form submit. If you will debug this you will notice that
additionalFields
selector take anything into submit that contain "form" attribute, so if you will manage to make your hidden input to contain attribute:form="customer_form"
, then your values should be posted with customer form. So your input should look like:You can do it by overriding
widget/grid/serializer.phtml
for your grid only or by overriding the proper block and setting this param through it.