How to create a custom grid from scratch

How to create a custom grid from scratch • Inchoo

How to create a custom grid from scratch

inchoo orders

We received a request from client, they wanted expanded order grid but still keep the default magento’s grid. For this example we’ll create new module named Inchoo Orders.

 

Step 1.

Create new module in etc/modules called Inchoo_Orders.xml

1
2
3
4
5
6
7
8
9
<?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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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.

1
2
3
4
<?php
class Inchoo_Orders_Helper_Data extends Mage_Core_Helper_Abstract
{
}

Step 6

Next step is to create controller for our grid.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?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

1
2
3
4
5
6
7
8
9
10
11
12
<?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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?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