Module Development Series – Magento Admin Module – Part2

In this blog post, we will see advanced functions and operations related to admin grid.

This blog is continuation of the previous blog where we saw basics of Admin Grid.

Edit Grid Row URL

If we need to specify an edit row URL of a grid, i.e when user click on any rows of the grid it goes to a specific URL. Add this function to the Grid.php file

public function getRowUrl($row)
	{
		return $this->getUrl('*/*/edit', array('id' => $row->getId()));
	}

The code is pretty obvious how it works. URL is of the editAction of your controller and it passed the row’s id as a parameter.

Drop Down Column Type

Suppose, you want a drop down type value in your grid i.e you want to show something like this in your grid.

Admin Grid Drop Down Type

Admin Grid Drop Down Type

So to add this is simple

$this->addColumn('dropdown1', array(
          'header'    => Mage::helper('employee')->__('Employee Type'),
          'align'     =>'left',
          'index'     => 'type',
		  'type'      => 'options',
		  'options'    => array('1' => 'Normal','2' => 'Admin' , '3' => 'Guest')
		));
Mass Actions

Mass Action are also very useful in a grid and used very often. Below is image of what exactly are mass options.

Magento Admin Grid Mass Action

Magento Admin Grid Mass Action

These used basically to do operations on multiple rows together. To add this, put in the code in your Grid.php file

protected function _prepareMassaction()
	{
		$this->setMassactionIdField('employee_id');
		$this->getMassactionBlock()->setFormFieldName('employee');

		$this->getMassactionBlock()->addItem('delete', array(
             'label'    => Mage::helper('employee')->__('Delete'),
             'url'      => $this->getUrl('*/*/massDelete'),
             'confirm'  => Mage::helper('employee')->__('Are you sure?')
		));

		$statuses = Mage::getSingleton('employee/status')->getOptionArray();

		array_unshift($statuses, array('label'=>'', 'value'=>''));
		$this->getMassactionBlock()->addItem('status', array(
             'label'=> Mage::helper('employee')->__('Change status'),
             'url'  => $this->getUrl('*/*/massStatus', array('_current'=>true)),
             'additional' => array(
                    'visibility' => array(
                         'name' => 'status',
                         'type' => 'select',
                         'class' => 'required-entry',
                         'label' => Mage::helper('employee')->__('Status'),
                         'values' => $statuses
		)
		)
		));
		return $this;
	}

So here

  • $this->getMassactionBlock()->setFormFieldName(’employee’):
    This line basically, tells the URL parameters in which all the ids are passed to the controller
  • ‘url’ => $this->getUrl(‘*/*/massDelete’) This sets the URL for the particular action.
  • ‘confirm’ => Mage::helper(’employee’)->__(‘Are you sure?’) This shows the user a confirm dialog before submitting the URL.

In your controller file, you need to implement these mass actions. Like for the delete action here the code to put in your EmployeeController.php

public function deleteAction() {
		if( $this->getRequest()->getParam('id') > 0 ) {
			try {
				$model = Mage::getModel('employee/employee');
				 
				$model->setId($this->getRequest()->getParam('id'))
					->delete();
					 
				Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Item was successfully deleted'));
				$this->_redirect('*/*/');
			} catch (Exception $e) {
				Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
				$this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
			}
		}
		$this->_redirect('*/*/');
	}
Export CSV/XML

If you want to add an import/export option to your grid as show below

Magento Grid Export CSV/XML

Magento Grid Export CSV/XML

We simple need to add these 2 line in our _prepareColumns() function

$this->addExportType('*/*/exportCsv', Mage::helper('employee')->__('CSV'));
$this->addExportType('*/*/exportXml', Mage::helper('employee')->__('XML'));

and your controller you need to add the action’s for these

public function exportCsvAction()
    {
        $fileName   = 'employee.csv';
        $content    = $this->getLayout()->createBlock('employee/adminhtml_employee_grid')
            ->getCsv();

        $this->_sendUploadResponse($fileName, $content);
    }

    public function exportXmlAction()
    {
        $fileName   = 'employee.xml';
        $content    = $this->getLayout()->createBlock('employee/adminhtml_employee_grid')
            ->getXml();

        $this->_sendUploadResponse($fileName, $content);
    }
Custom Search/Filter For a Column

Suppose in a single column of your grid, you want the search function to work differently. Example you have a joined many tables in your collection, and for a column/index you want the search to work differently or not work at all.
Here is how to do it, we need to override the protected function _addColumnFilterToCollection($column) function. So in your Grid.php file

protected function _addColumnFilterToCollection($column)
    {
        if ($this->getCollection()) {
            if ($column->getId() == 'websites') {
                $this->getCollection()->joinField('websites',
                    'catalog/product_website',
                    'website_id',
                    'product_id=entity_id',
                    null,
                    'left');
            }
        }
        return parent::_addColumnFilterToCollection($column);
    }
Ajax Based Grid

If in your grid, you want the searching/paging and other operating to all work ajax based, this is what you need to do. In your Grid.php file in the constructor add these two lines

$this->setSaveParametersInSession(true);
$this->setUseAjax(true);

and in Grid.php add the function

public function getGridUrl()
    {
        return $this->getUrl('*/*/grid', array('_current'=>true));
    }

This the URL which is called in the Ajax Request, to the get the content of the grid.
and in your EmployeeContrller.php add the action

public function gridAction()
    {
        $this->loadLayout();
        $this->getResponse()->setBody(
            $this->getLayout()->createBlock('employee/adminhtml_employee_grid')->toHtml()
        );
    }
Adding Different Buttons To Grid

By default in your Grid, you get only option have an “Add” button like we have an “Add Employee” button. But suppose, we want to have multiple buttons in our grid as show below

Magento Admin Grid Buttons

Magento Admin Grid Buttons

To make this happen, we need to edit our Grid Container File i.e the Employee.php file and in the constructor add the code

public function __construct()
	{
		$this->_controller = 'adminhtml_employee';
		$this->_blockGroup = 'employee';
		$this->_headerText = Mage::helper('employee')->__('Employee Manager');
		$this->_addButtonLabel = Mage::helper('employee')->__('Add Employee');


		$this->_addButton('button1', array(
            'label'     => Mage::helper('employee')->__('Button Label1'),
            'onclick'   => 'setLocation(\'' . $this->getUrl('*/*/button1') .'\')',
            'class'     => 'add',
		));
		$this->_addButton('button2', array(
            'label'     => Mage::helper('employee')->__('Button Label2'),
            'onclick'   => 'setLocation(\'' . $this->getUrl('*/*/button2') .'\')',
            'class'     => 'remove',
		));


		parent::__construct();
	}
Change Default Page Size

For this you need to overwrite the _preparePage() function, in your Grid.php make this changes

protected function _preparePage()
    {
        $this->getCollection()->setPageSize($this->getParam($this->getVarNameLimit(), $this->_defaultLimit));
        $this->getCollection()->setCurPage($this->getParam($this->getVarNamePage(), $this->_defaultPage));
    }

and you can set the $this->_defaultLimit and $this->_defaultPage as per your wish.

Custom Column Type For Grid

This has been explained in another blog post.

Adding Different Options To Grid Rows

If you want to option to rows, than Edit link e.g as shown below

Magento Grid Action

Magento Grid Action

$this->addColumn('action',
		array(
                'header'    => Mage::helper('employee')->__('Action'),
                'type'      => 'action',
                'getter'     => 'getId',
                'actions'   => array(
						array(
                        'caption' => Mage::helper('employee')->__('Edit'),
                        'url'     => $this->getUrl("*/*/edit"),
                        'field'   => 'id'
                        ),
                        array(
                        'caption' => Mage::helper('employee')->__('Delete'),
                        'url'     => $this->getUrl("*/*/delete"),
                        'field'   => 'id'
                        )
                        ),
			                'filter'    => false,
			                'sortable'  => false
                        ));

There are many other things we can customize in our grid. You need to open the class Mage_Adminhtml_Block_Widget_Grid and explore other possibilities.

  • Kiran

    Very great article, thank you very much Manish

    • Manish Prakash

      Thanks 🙂

  • Dkumar

    Hi All,

    Is the any way to show/list data in grid not from the db, like I want to show the data from api to grid in Magento.

    • Manish Prakash

      Hi,

      Good question, I have not implemented such a solution myself. But as far as I think either you need to create a very customized gird i.e edit default magento grid features or you can store the data returned from api to database table and then show it on grid.

  • Andrew Griggs

    Great article, and such a great help!

    But, your Mass Actions controller code is wrong, as it is only set to delete one ID.

    public function massDeleteAction() { //NOTE: massDelete        if( $this->getRequest()->getParam(‘id’) > 0 ) {            try {                $model = Mage::getModel(’employee/employee’);  foreach ($this->getRequest()->getParam(‘id’) as $id) { $model->load($id)->delete();
    } //NOTE: The LOOP required: from http://inchoo.net/ecommerce/magento/how-to-add-massactions-to-magentos-grid/
                     Mage::getSingleton(‘adminhtml/session’)->addSuccess(Mage::helper(‘adminhtml’)->__(‘Item was successfully deleted’));                $this->_redirect(‘*/*/’);            } catch (Exception $e) {                Mage::getSingleton(‘adminhtml/session’)->addError($e->getMessage());                $this->_redirect(‘*/*/edit’, array(‘id’ => $this->getRequest()->getParam(‘id’)));            }        }        $this->_redirect(‘*/*/’);    }

  • The Export to CSV should have this line of code in the controller:

    $this->_prepareDownloadResponse($fileName, $content);

    http://www.octopus-it.com

  • Matt Williams

    I just wanna say thank you, Manish, for taking the time to actually explain what the different bits of code do on the road to creating the admin grid and the advanced grid features.  Thanks to you, I finally have a grasp on the parts I was missing before.  Thanks a million!

  • Hi Manish,
    Thanks for sharing your valuable knowledge, i’m having
    some doubts when we clicks on CSV export, its exporting the contents in
    the grid, how to add/remove some column while exporting?
    ie., If
    the order status grid having order_id, status means, i want to add
    address details while exporting the CSV file. How to do that? Thanks in
    advance

  • shiv

    hi
    i am creating site with multi views store and i want to add product images differently to all store views with the same page without using store view switcher in magento admin panel