Add Company column to Customers Admin Grid with Observer
-
13-12-2019 - |
Question
I want to add the "Company" column from the customer's Address attributes.
Is there any way to populate this column through an observer or do I need to extend the prepareCollection
or preparePage
functions?
Working Code:
Observer is set up on event core_block_abstract_prepare_layout_before
XML
/app/code/local/Mbs/Changegrid/etc/config.xml
<?xml version="1.0"?>
<config>
<modules>
<Mbs_Changegrid>
<version>0.4.0</version>
</Mbs_Changegrid>
</modules>
<global>
<models>
<mbs_changegrid>
<class>Mbs_Changegrid_Model</class>
</mbs_changegrid>
</models>
</global>
<adminhtml>
<events>
<core_block_abstract_to_html_before>
<observers>
<changegrid_before_block>
<class>Mbs_Changegrid_Model_Observer</class>
<method>beforeBlockToHtml</method>
</changegrid_before_block>
</observers>
</core_block_abstract_to_html_before>
<eav_collection_abstract_load_before>
<observers>
<changegrid_collection_load>
<class>Mbs_Changegrid_Model_Observer</class>
<method>beforeCollectionLoad</method>
</changegrid_collection_load>
</observers>
</eav_collection_abstract_load_before>
</events>
</adminhtml>
</config>
PHP
/app/code/local/Mbs/Changegrid/Model/Observer.php
class Mbs_Changegrid_Model_Observer {
public function beforeBlockToHtml(Varien_Event_Observer $observer) {
$grid = $observer->getBlock();
/**
* Mage_Adminhtml_Block_Customer_Grid
*/
if ($grid instanceof Mage_Adminhtml_Block_Customer_Grid) {
$grid->addColumnAfter(
'company',
array(
'header' => Mage::helper('customer')->__('Company'),
'index' => 'company'
),
'name'
);
}
}
public function beforeCollectionLoad(Varien_Event_Observer $observer) {
$collection = $observer->getCollection();
if (!isset($collection)) {
return;
}
/**
* Mage_Customer_Model_Resource_Customer_Collection
*/
if ($collection instanceof Mage_Customer_Model_Resource_Customer_Collection) {
/* @var $collection Mage_Customer_Model_Resource_Customer_Collection */
$collection->addAttributeToSelect('company');
$addressCollection = Mage::getModel('customer/address')->getCollection()->addAttributeToSelect('company');
$addressCollection->getSelect()->limit(1);
$address = $addressCollection->getFirstItem();
foreach ($address->getAttributes() as $attribute) {
if (is_null($attribute->getAttributeID()) || is_null($attribute->getFrontendLabel()) || ($attribute->getFrontendLabel() == '')) {
continue;
}
$collection->joinAttribute($attribute->getName(), 'customer_address/' . $attribute->getName(), 'default_billing', null, 'left');
}
}
}
}
Solution
It is possible thru rewrite or observer: (observer is better to prevent rewrite conflicts)
Using Observer
Configure your 2 observers: loading the column to grid and loading of collection
<adminhtml>
<events>
<core_block_abstract_to_html_before>
<observers>
<{observer_name}>
<class>{namespace}_{module}/observer</class>
<method>beforeBlockToHtml</method>
</{observer_name}>
</observers>
</core_block_abstract_to_html_before>
<eav_collection_abstract_load_before>
<observers>
<{observer_name}>
<class>{namespace}_{module}/observer</class>
<method>beforeCollectionLoad</method>
</{observer_name}>
</observers>
</eav_collection_abstract_load_before>
</events>
</adminhtml>
Then create your observer class with the methods in the declaration
class {Namespace}_{Module}_Model_Observer
{
public function beforeBlockToHtml(Varien_Event_Observer $observer)
{
$grid = $observer->getBlock();
/**
* Mage_Adminhtml_Block_Customer_Grid
*/
if ($grid instanceof Mage_Adminhtml_Block_Customer_Grid) {
$grid->addColumnAfter(
'{column_code}',
array(
'header' => Mage::helper('{Module}_customer')->__('{{column_name}}'),
'index' => '{column_code}'
),
'entity_id'
);
}
}
public function beforeCollectionLoad(Varien_Event_Observer $observer)
{
$collection = $observer->getCollection();
if (!isset($collection)) {
return;
}
/**
* Mage_Customer_Model_Resource_Customer_Collection
*/
if ($collection instanceof Mage_Customer_Model_Resource_Customer_Collection) {
/* @var $collection Mage_Customer_Model_Resource_Customer_Collection */
$collection->addAttributeToSelect('{attribute_code}');
}
}
}
See this answer: https://magento.stackexchange.com/a/5986/21518
Using Rewrite
Rewrite the grid block's _prepareCollection
method and add your column to the collection.
See this answer: https://magento.stackexchange.com/a/5975/21518
OTHER TIPS
No need to rewrite, can all be done in an observer.
In the following code, I used the event: adminhtml_block_html_before
The code below is to insert two new columns, called 'Referred By' and a lookup list one for 'State', into the Newsletter Grid.
The idea is the same, and you should be able to use it in your own grid customizations.
1am here now, so just going place the code. ask if you need any clarifications. I did add in some comments ;)
The code also includes a means to fix/enable filtering of the column
I hope this helps.
public function adminhtml_block_html_before(Varien_Event_Observer $observer)
{
try {
$event = $observer->getEvent();
if ($event->getBlock() instanceof
Mage_Adminhtml_Block_Newsletter_Subscriber_Grid
) {
$this->_grid = $event->getBlock();
$this->_collection = $this->_grid->getCollection();
/**
YOU COULD ADJUST COLLECTION HERE
ADD NEW FIELD FILTERS< COLUMNS ETC **/
$columnData = array(
'header' => 'Referred By',
'index' => 'referred_by',
'type' => 'text',
);
$this->_grid->addColumn('referred_by', $columnData);
$options = array();
$regions = mage::helper('proxiblue_enhancedsubscription')->getRegionCollection();
foreach ($regions as $row) {
$options[$row['code']] = $row['name'];
}
$columnData = array(
'header' => 'State',
'index' => 'state',
'type' => 'options',
'options' => $options,
'width' => 400
);
$this->_grid->addColumnAfter('state', $columnData, 'lastname');
$this->_grid->sortColumnsByOrder();
// rebuild the filters
$filter = $this->_grid->getParam($this->_grid->getVarNameFilter(), null);
if (is_null($filter)) {
return $this;
}
$this->_collection->clear();
if (is_string($filter)) {
$data = $this->_grid->helper('adminhtml')->prepareFilterString($filter);
$this->_setFilterValues($data);
} else {
if ($filter && is_array($filter)) {
$this->_setFilterValues($filter);
}
}
// force a reload of the collection
$this->_collection->load();
}
} catch (Exception $e) {
mage::logException($e);
}
return $this;
}
protected function _setFilterValues($data)
{
foreach ($this->_grid->getColumns() as $columnId => $column) {
if (isset($data[$columnId]) && (!empty($data[$columnId]) || strlen($data[$columnId]) > 0)
&& $column->getFilter()
) {
$column->getFilter()->setValue($data[$columnId]);
$this->_addColumnFilterToCollection($column);
}
}
return $this;
}
protected function _addColumnFilterToCollection($column)
{
if ($this->_collection) {
$field = ($column->getFilterIndex()) ? $column->getFilterIndex() : $column->getIndex();
if ($column->getFilterConditionCallback()) {
call_user_func($column->getFilterConditionCallback(), $this->getCollection(), $column);
} else {
$cond = $column->getFilter()->getCondition();
if ($field && isset($cond)) {
$this->_collection->addFieldToFilter($field, $cond);
}
}
}
return $this;
}