Question

I have added "Company" field in admin customer grid, but the issue i face is sorting not working.

I have override Mage_Adminhtml_Block_Customer_Grid Class and added below code:

 protected function _prepareCollection()
    {
        parent::_prepareCollection();

        $collection = Mage::getResourceModel('customer/customer_collection')
            ->addNameToSelect()
            ->addAttributeToSelect('email')
            ->addAttributeToSelect('created_at')
            ->addAttributeToSelect('group_id')
            ->addAttributeToSelect('company')
            ->joinAttribute('billing_postcode', 'customer_address/postcode', 'default_billing', null, 'left')
            ->joinAttribute('billing_city', 'customer_address/city', 'default_billing', null, 'left')
            ->joinAttribute('billing_telephone', 'customer_address/telephone', 'default_billing', null, 'left')
            ->joinAttribute('billing_region', 'customer_address/region', 'default_billing', null, 'left')
            ->joinAttribute('billing_company', 'customer_address/company', 'default_billing', null, 'left')
            ->joinAttribute('billing_country_id', 'customer_address/country_id', 'default_billing', null, 'left'); 

        $this->setCollection($collection); 

        return $this;
    }
    protected function _prepareColumns()
    {


        $this->addColumn('company', array(
            'header'    =>  Mage::helper('customer')->__('Company'),
            'width'     =>  '150',
            'index'     =>  'billing_company',

        )); 
        $this->addColumnsOrder('billing_company', 'email');
        return parent::_prepareColumns();
    }

Can anyone have solution for above issue?

Was it helpful?

Solution

The problem is that Magento does a lot of required work on the collection in Mage_Adminhtml_Block_Widget_Grid::_prepareCollection(), that is, when you call parent::_prepareCollection() at the beginning of your overwritten method.
What happens is

  1. You call the original parent _prepareCollection()
  2. The original collection is initialized
    in Mage_Adminhtml_Block_Customer_Grid::_prepareCollection()
  3. The collection is assigned to the grid
    $this->setCollection()
  4. The abstract parent grid _prepareCollection() is called.
  5. During this method call, the order is applied, which at this point in time is the default order since the collection hasn't got the company or billing_company attribute in it's select list yet.
    $this->_setCollectionOrder($this->_columns[$columnId]);
  6. After the parents _prepareCollection() method finished, you instantiate a new customer collection, and add all the attributes you want to display, and assign it to the grid.
  7. The order isn't reapplied, since you don't call the abstract grids _prepareCollection again.

Which you can't, since calling parent::_prepareCollection() would once again override your collection with the original one.

One possible solution would be to duplicate the logic from the abstract grid's _prepareCollection() method, but copying code is always bad for maintainability.

A better solution is to look for a suitable hook method, that gives you the chance to add your new company column to the existing collection before the sort order and filtering is applied.

Looking at the first few lines of Mage_Adminhtml_Block_Widget_Grid::_prepareCollection() we can see just what we need:

protected function _prepareCollection()
{
    if ($this->getCollection()) {

        $this->_preparePage();

So, instead of overwriting the protected function _prepareCollection() in your block, try this instead:

protected function _preparePage()
{
    $this->getCollection()
        ->joinAttribute('billing_company', 'customer_address/company', 'default_billing', null, 'left');
    return parent::_preparePage();
}

It's all a matter of timing and inserting the custom logic at the right point during the process flow.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top