How to create a custom grid from scratch

inchoo orders

We received a request from a client where they wanted to implement an expanded order grid while still keeping the default Magento’s one. For this example we’ll create a new module named Inchoo Orders.

Step 1.

Create new module in etc/modules called Inchoo_Orders.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Inchoo_Orders>
            <active>true</active>
            <codePool>community</codePool>
        </Inchoo_Orders>
    </modules>
</config>

Step 2.

Next thing we’ll do is create folder Inchoo/Orders inside app/code/community and inside we’ll make few folders: Block, controllers, etc, Helper.

inchoo_orders

Step 3.

Create config.xml inside etc folder.

<?xml version="1.0"?>
<config>
    <modules>
        <Inchoo_Orders>
            <version>0.0.0.1</version>
        </Inchoo_Orders>
    </modules>
    <global>
        <models>
            <inchoo_orders>
                <class>Inchoo_Orders_Model</class>
                <resourceModel>inchoo_orders_resource</resourceModel>
            </inchoo_orders>
        </models>
        <resources>
            <inchoo_orders_setup>
                <setup>
                    <module>Inchoo_Orders</module>
                </setup>
            </inchoo_orders_setup>
        </resources>
        <blocks>
            <inchoo_orders>
                <class>Inchoo_Orders_Block</class>
            </inchoo_orders>
        </blocks>
        <helpers>
            <inchoo_orders>
                <class>Inchoo_Orders_Helper</class>
            </inchoo_orders>
        </helpers>
    </global>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <inchoo_orders before="Mage_Adminhtml">Inchoo_Orders_Adminhtml</inchoo_orders>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>

Step 4

Create adminhtml.xml file inside etc folder which will add a link to our orders page in magento admin panel.

<?xml version="1.0"?>
<config>
    <menu>
        <sales>
            <children>
                <inchoo_orders translate="title" module="inchoo_orders">
                    <sort_order>10</sort_order>
                    <title>Orders - Inchoo</title>
                    <action>adminhtml/order/</action>
                </inchoo_orders>
            </children>
        </sales>
    </menu>
</config>

Step 5

Create blank helper class.

<?php
class Inchoo_Orders_Helper_Data extends Mage_Core_Helper_Abstract
{
}

Step 6

Next step is to create controller for our grid.

<?php
class Inchoo_Orders_Adminhtml_OrderController extends Mage_Adminhtml_Controller_Action
{
    public function indexAction()
    {
        $this->_title($this->__('Sales'))->_title($this->__('Orders Inchoo'));
        $this->loadLayout();
        $this->_setActiveMenu('sales/sales');
        $this->_addContent($this->getLayout()->createBlock('inchoo_orders/adminhtml_sales_order'));
        $this->renderLayout();
    }
    public function gridAction()
    {
        $this->loadLayout();
        $this->getResponse()->setBody(
            $this->getLayout()->createBlock('inchoo_orders/adminhtml_sales_order_grid')->toHtml()
        );
    }
    public function exportInchooCsvAction()
    {
        $fileName = 'orders_inchoo.csv';
        $grid = $this->getLayout()->createBlock('inchoo_orders/adminhtml_sales_order_grid');
        $this->_prepareDownloadResponse($fileName, $grid->getCsvFile());
    }
    public function exportInchooExcelAction()
    {
        $fileName = 'orders_inchoo.xml';
        $grid = $this->getLayout()->createBlock('inchoo_orders/adminhtml_sales_order_grid');
        $this->_prepareDownloadResponse($fileName, $grid->getExcelFile($fileName));
    }
}

Step 7

Next thing we do is create grid container in Block/Adminhtml/Sales/Order.php

<?php
class Inchoo_Orders_Block_Adminhtml_Sales_Order extends Mage_Adminhtml_Block_Widget_Grid_Container
{
    public function __construct()
    {
        $this->_blockGroup = 'inchoo_orders';
        $this->_controller = 'adminhtml_sales_order';
        $this->_headerText = Mage::helper('inchoo_orders')->__('Orders - Inchoo');
        parent::__construct();
        $this->_removeButton('add');
    }
}

Step 8

Last step is making grid class in Block/Adminhtml/Sales/Order/Grid.php

<?php
class Inchoo_Orders_Block_Adminhtml_Sales_Order_Grid extends Mage_Adminhtml_Block_Widget_Grid
{
    public function __construct()
    {
        parent::__construct();
        $this->setId('inchoo_order_grid');
        $this->setDefaultSort('increment_id');
        $this->setDefaultDir('DESC');
        $this->setSaveParametersInSession(true);
        $this->setUseAjax(true);
    }
    protected function _prepareCollection()
    {
        $collection = Mage::getResourceModel('sales/order_collection')
            ->join(array('a' => 'sales/order_address'), 'main_table.entity_id = a.parent_id AND a.address_type != \'billing\'', array(
                'city'       => 'city',
                'country_id' => 'country_id'
            ))
            ->join(array('c' => 'customer/customer_group'), 'main_table.customer_group_id = c.customer_group_id', array(
                'customer_group_code' => 'customer_group_code'
            ))
            ->addExpressionFieldToSelect(
                'fullname',
                'CONCAT({{customer_firstname}}, \' \', {{customer_lastname}})',
                array('customer_firstname' => 'main_table.customer_firstname', 'customer_lastname' => 'main_table.customer_lastname'))
            ->addExpressionFieldToSelect(
                'products',
                '(SELECT GROUP_CONCAT(\' \', x.name)
                    FROM sales_flat_order_item x
                    WHERE {{entity_id}} = x.order_id
                        AND x.product_type != \'configurable\')',
                array('entity_id' => 'main_table.entity_id')
            )
        ;
        $this->setCollection($collection);
        parent::_prepareCollection();
        return $this;
    }
    protected function _prepareColumns()
    {
        $helper = Mage::helper('inchoo_orders');
        $currency = (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE);
        $this->addColumn('increment_id', array(
            'header' => $helper->__('Order #'),
            'index'  => 'increment_id'
        ));
        $this->addColumn('purchased_on', array(
            'header' => $helper->__('Purchased On'),
            'type'   => 'datetime',
            'index'  => 'created_at'
        ));
        $this->addColumn('products', array(
            'header'       => $helper->__('Products Purchased'),
            'index'        => 'products',
            'filter_index' => '(SELECT GROUP_CONCAT(\' \', x.name) FROM sales_flat_order_item x WHERE main_table.entity_id = x.order_id AND x.product_type != \'configurable\')'
        ));
        $this->addColumn('fullname', array(
            'header'       => $helper->__('Name'),
            'index'        => 'fullname',
            'filter_index' => 'CONCAT(customer_firstname, \' \', customer_lastname)'
        ));
        $this->addColumn('city', array(
            'header' => $helper->__('City'),
            'index'  => 'city'
        ));
        $this->addColumn('country', array(
            'header'   => $helper->__('Country'),
            'index'    => 'country_id',
            'renderer' => 'adminhtml/widget_grid_column_renderer_country'
        ));
        $this->addColumn('customer_group', array(
            'header' => $helper->__('Customer Group'),
            'index'  => 'customer_group_code'
        ));
        $this->addColumn('grand_total', array(
            'header'        => $helper->__('Grand Total'),
            'index'         => 'grand_total',
            'type'          => 'currency',
            'currency_code' => $currency
        ));
        $this->addColumn('shipping_method', array(
            'header' => $helper->__('Shipping Method'),
            'index'  => 'shipping_description'
        ));
        $this->addColumn('order_status', array(
            'header'  => $helper->__('Status'),
            'index'   => 'status',
            'type'    => 'options',
            'options' => Mage::getSingleton('sales/order_config')->getStatuses(),
        ));
        $this->addExportType('*/*/exportInchooCsv', $helper->__('CSV'));
        $this->addExportType('*/*/exportInchooExcel', $helper->__('Excel XML'));
        return parent::_prepareColumns();
    }
    public function getGridUrl()
    {
        return $this->getUrl('*/*/grid', array('_current'=>true));
    }
}

Our new custom orders page can be accessed by going to Sales -> Orders – Inchoo in admin panel.

link in admin

End result should be something like this:

inchoo orders grid

29
Top

Care to rate this post?

Author

Vedran Sola

Ex Inchooer

Vedran worked at Inchoo as a Backend Developer from December 2012 to April 2014

Other posts from this author

Discussion 29 Comments

Add Comment
  1. Congrats Vedran on your first post!

  2. Very interesting. For my experience a current problem is to create a master/details grid. Have you got a road to?
    regards
    filippo.

  3. Hi,

    I have followed your guide but when I click on the link it simple gives me a blank screen not showing the grid. One thing i was wondering, where does it call the gridAction from the controller?

  4. Vedran Sola

    @Kieran

    gridAction is being called by getGridUrl method in Grid.php and its purpose is to enable grid filtering using ajax.

  5. Alex

    Hey Vedran,
    This looks very interesting. I got lost at steps 5 and 6. What files should contain the blank helper class and the controller for our grid?
    Thanks,

  6. Vedran Sola

    Data.php is helper and controller class should go to controllers/Adminhtml/Order.php

  7. Nice!

  8. Hissam Roohi

    When i click the Orders- Inchoo sub menu , i am getting the error ‘The page you requested was not found, and we have a fine guess why.’

    After clicking it is redirecting the below url :

    “http://localhost/magento17/index.php/admin/order/index/key/1bce285af813fee9aa5d18881474c09e/”

    @Vedran Sola -Can you please help me out

  9. Hello ,

    I am facing the same problem as of Hissam Roohi.

    What could be the issue?? I think that might be the issue due to some wrong configuration. Can you please let me know what could be the issue

  10. i just implemented this on our of our projects and i must say it worked flawlessly.

  11. Mark

    Hi,

    I am getting the same error as Hissam and Kaysellers.

    What version does this work on?

  12. Zvonimir Buric

    @Kaysellers
    Hi,
    did you try to clear the cache?

  13. Vedran Sola

    Take a look at screenshot, perhaps you’re missing something: http://i.imgur.com/odIXoUz.png?1

  14. ranga

    i did it but page load with empty screen there is no data or nothing no errors

  15. I got same errors so I just changed few lines.

    Wrong :
    class Inchoo_Orders_Adminhtml_OrderController extends Mage_Adminhtml_Controller_Action
    {

    Right :
    include(‘Mage/Adminhtml/controllers/Sales/OrderController.php’);
    class Inchoo_Orders_Adminhtml_OrdersController extends Mage_Adminhtml_Sales_OrderController
    {

    and

    in adminhtml.xml

    10
    Orders – Inchoo
    order/adminhtml_orders

  16. Neet

    Hi,
    I am running magento 1.7, and followed the steps above to create a new grid. However when I click on it from the admin page, I get a 404, page not found error. I don’t see the new grid details :((.
    Please help.

    Thanks,
    Neet

  17. Neet

    Hi,
    I can see the Order – Inchoo under the Sales tab in the admin. However when I click on it, it gives me a 404 error.
    Below is the link it is pointing to:
    http://127.0.1.1/bakery/index.php/order/adminhtml_order/index/key/463b6f9049cf6c0eca7f56eba7a9b7ad/

    Is this link correct? I have verified the file structure and it is same as mentioned above.
    I am guessing something is wrong with my etc/adminhtml.xml.

    10
    Orders – Bakery
    order/adminhtml_order

    Please advice.

    Thanks,
    Neet

  18. Thanks so much!

    I’ve been trying to add the Customer group to the grid for days now…

    Regards,
    Seb

  19. Rushit

    Y i need to just make a file in helper when there is no data in it ? I am just declaring the file & not writing any content in it.

  20. sandeep

    how can i do same for managed products

  21. benblee

    Got things working and this is a great walk through.

    Two things I noticed are that a database table prefix needs to be defined in the Grid.php file code and that the row does not link to the order details.

    Is it possible to get the row linked to the order details?

  22. benblee

    Looks like this adds the row url, which I just pulled from the core Grid.php file:

    public function getRowUrl($row)
    {
    if (Mage::getSingleton(‘admin/session’)->isAllowed(‘sales/order/actions/view’)) {
    return $this->getUrl(‘*/sales_order/view’, array(‘order_id’ => $row->getId()));
    }
    return false;
    }

    That added just above the grid url code near the end.

  23. benblee

    Sam at RocketTheme helped me out with the database prefix issue.

    Change out the table name:

    sales_flat_order_item

    With this:

    '.Mage::getSingleton('core/resource')-&gt;getTableName('sales_flat_order_item').'

    That will retrieve any prefix for your current install.

  24. Carmen

    Thank you very much for your post!
    Anyone know how to generate in a cronjob the csv with this content?
    is for integration with a sales soft
    thankyou in advance

  25. noman

    I make my own module using your concept but grid content are not shown… help me out to fix this problem

  26. I am gettign this error whenever I tried to open this module from admin site
    Parse error: syntax error, unexpected ‘Â Â Â Â public’ (T_STRING), expecting function (T_FUNCTION) in C:\xampp\htdocs\magento\app\code\community\Inchoo\Orders\controllers\Adminhtml\OrderController.php on line 9

    Can anyone help me for that

  27. suchitra

    Hi,
    This is very good extension. In our custom grid orders are showing but it better link provide to the orders to the order detailed page. Can you please guide the hyperlink to redirect the order page when we click on that order.

  28. Mike

    For those getting a 404 Not Found Error when trying to access the grid, I found the issue was where I put my OrderController.php file. It needs to be Inchoo/Orders/controllers/Adminhtml/OrderController.php

    Originally I had put it in Inchoo/Orders/controllers/OrderController.php and this doesn’t work.

  29. Nikunj

    i try to use this code but not working and give black screen.

    please Vedran Sola why this not work??

    thanks in advanced

Add Your Comment

Please wrap all source codes with [code][/code] tags.
Top