Filter order grid by multiple ID’s

We all know how great Magento grids can be – there is no alternative when it comes to displaying data in a efficient manner.

Our clients sometimes (almost always) have specific requirements when it comes to Magento. One of them had a request to be able to filter the order grid by multiple order ID’s.

This can be useful if you have a number of orders you’d like to track – filtering them one by one can be tedious and time-consuming task.

The Trickery

The trick I’m about to show you can be done in almost any grid, once you know how it’s done.
Firstly, rewrite your order grid block (appcodecoreMageAdminhtmlBlockSalesOrderGrid.php) – I presume you’ll know how to do this. 🙂

In your _prepareColumns() method, add a element to the array as shown below (line 8)

protected function _prepareColumns()
{
$this->addColumn('real_order_id', array(
'header'=> Mage::helper('sales')->__('Order #'),
'width' => '250px',
'type' => 'text',
'index' => 'increment_id',
'filter_condition_callback' => array($this, 'spaceSeparatedFilter')//calling spaceSeparatedFilter method
));
....
}

Renderers are being called when a row is being rendered in our grid, and get passed the cell that’s being rendered as a parameter.

Filter callbacks, on the other hand, get called with the entire column and collection as parameters. As a result, we can create our own method, call it via filter_condition_callback element, and do custom queries to the database, catch the input from our grid, etc.

This is exactly what we’ll do.

Our filter callback will call the spaceSeparatedFilter() method and pass it the real_order_id column as a parameter. Let’s declare our method (inside the same Grid.php file):

protected function spaceSeparatedFilter($collection, $column)
{
if (!$value = $column->getFilter()->getValue()) {
return $this;
}
//if there was a space input
else if(preg_match('/s+/', $value))
{
//explode by space, getting array of IDs
$val = explode(" ", $value);
//filter the collection, where collection index (order_id) is present in $val array
$this->getCollection()->addAttributeToFilter($column->getData('index'), array('in'=>$val));
}
else
{
//else use default grid filter functionality (like $value input)
$this->getCollection()->addAttributeToFilter($column->getData('index'), array('like' => '%'.$value.'%'));
}
return $this;
}

These two pieces of code enable you to filter orders by multiple order id’s, as long as you separate them with a space. If you haven’t entered a space, it will work as default (i.e. filtering orders with an IDLIKE‘ your query).

You can also use all features of the grid: sorting, filtering, export, without any problems.

Hope this will be useful to some of you.

View this code snippet on GitHub.