How to filter a grid in Magento 1

posted by 1 year ago and updated 1 year ago

Note: This tutorial assumes prior knowledge into building modules, only parts of the code are included to solve a particular problem.

Filtering grids can work out of the box but sometimes you might need to create your own custom filter. There are two ways we are aware of to filter data in your columns.

  • defining a filter_condition_callback in $this->addColumn()
  • define a filter class filter in $this->addColumn()

In our example we will use our grid class Underthecocotree_Subscribers_Block_Adminhtml_Promo_Quote_Edit_Tab_Coupons_Grid from our tutorial on How to Override Coupon Grid for Magento 1

How to filter a grid with filter_condition_callback

protected function _prepareColumns()
{
    $this->addColumnAfter('expired', array(
        'header'  => Mage::helper('underthecocotree_subscribers_helper')->__("Expired"),
        'type'    => 'text',
        'type'    => 'options',
        'options' => Mage::getSingleton('adminhtml/system_config_source_yesno')->toArray(),
        'index'   => 'expired',		
        'filter_condition_callback' => array($this, '_expiredFilter'),

        ), 'expires_at');
}

// function that takes care of the filter
protected function _expiredFilter($collection, $column)
{	
     $value = $column->getFilter()->getValue();

		$collection->getSelect()->where('subscribers.expired = ?', $value);

      return $this;
}

How to filter a grid with a class

The filter_condition_callback makes it easy to create a function within the grid class. You might want to create different scenarios and keep filtering to a different class. So how do we create a filter class for our grid?

First from our Grid.php class we need to tell magento to user our filter class.

protected function _prepareColumns()
{
    $this->addColumnAfter('expired', array(
		// ...
        'filter' => new Underthecocotree_Subscribers_Block_Adminhtml_Promo_Quote_Edit_Tab_Coupons_Filter_Expired, 

		// or
		// 'filter' => 'underthecocotree_subscribers_block/adminhtml_promo_quote_edit_tab_coupons_filter_expired'

		// ...
        ), 'expires_at');
}

The magento way is to add the string that resolves through your config.xml file but we feel sometimes it is easier to user the full class name.

We create our filter class Expired.php inside a directory called Filter in the same level as the Grid.php

  • Grid.php
  • Filter/Expired.php

Filter class: Underthecocotree_Subscribers_Block_Adminhtml_Promo_Quote_Edit_Tab_Coupons_Filter_Expired

class Underthecocotree_Subscribers_Block_Adminhtml_Promo_Quote_Edit_Tab_Coupons_Filter_Expired extends Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Select
{

   public function __construct()
   {
		// log to see if it is being called
      parent::__construct();
   }

   protected function _getOptions()
   {
      return array(
         array('value' => null, 'label' => Mage::helper('adminhtml')->__('')),
         array('value' => 1, 'label' => Mage::helper('adminhtml')->__('Yes')),
         array('value' => 0, 'label' => Mage::helper('adminhtml')->__('No')),
      );
   }

   public function getCondition()
   {
      if (null === $this->getValue()) {
         return null;
      }

      return array('eq' => $this->getValue());
   }

}

In our Expired.php file we are extending Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Select which also gives us access to _getOptions() method. This method will give us a drop down menu in our filter header bar.

The filtering is done by the getCondition method. The filtering works a bit different. We are already getting the collection and the column by using the class. All we do is return an array with a condition match.

How to disable filtering and sorting

To disable filtering and sorting we have to set filter and sortable to false when we addToColumn()

protected function _prepareColumns()
{
  $this->addColumnAfter('expired', array(
            // ...

      'filter' => false,
      'sortable' => false,

            // ...
      ), 'expires_at');
}

Troubleshooting filtering

The best way to see if your filter function or class is called, is to log a message in our system.log Mage::log("filter called");

You can add the log method in the:

  • filter_condition_callback In our example expiredFilter()
  • constructor of Filter/Expired.php
  • Inside getCondition() method

We were having trouble with our filtering not working, we noticed that
adding return Mage_Adminhtml_Block_Widget_Grid::_prepareCollection(); in our _prepareCollection() function did the trick.

Sometimes a grid filter won’t work because the getUrl() is not defined properly.

In summary

Sometimes filtering will work out of the box when you add a column. At other times you might need to have more structure to your application or do more complicated logic.

The filter_condition_callback is your quick hack to filtering, while the filtering class is a more advanced way of doing it.

Check if your filtering is working by default and if not, start digging deeper into filtering with magento.