Take the 2-minute tour ×
Magento Stack Exchange is a question and answer site for users of the Magento e-Commerce platform. It's 100% free, no registration required.

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?

share|improve this question
    
I think you need to put filter index if sorting is not working –  Mufaddal Jul 19 '13 at 7:00

1 Answer 1

up vote 4 down vote accepted

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.

share|improve this answer
    
Thanks Vinai. It works great –  Bijal Bhavsar Jul 19 '13 at 8:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.