Home/How to Make Editable Grid in Magento

How to Make Editable Grid in Magento

Published On: 20 June 2014.By .
  • Product & platform Engineering

A grid in Magento provides you the ability to list the information e.g. List of products, orders etc. It also give you facility to perform action in bulk but it does not allow you to send extra information though it e.g you want to change the quantity of the products from the grid. You can change it in bulk but can not assign to individual.

This tutorial will give you step by step instruction to create a grid in which you can also add input fields in columns, send those values to controller and perform releavant action.

I am taking the example of changing the quantity of products in bulk from the grid.

Step 1: create a new module file

app/etc/modules/Auriga_Editable.xml

<div style=”color:white;background-color:grey;overflow:auto”>

<pre>

<?xml version="1.0"?>

<config>

 <modules>

 <Auriga_Editable>

 <active>true</active>

 <codePool>local</codePool>

 <version>0.1.0</version>

 </Auriga_Editable>

 </modules>

</config>

</pre>

</div>


Step 2: create config file of the module

app/code/local/Auriga/Editable/etc/config.xml

<div style=”color:white;background-color:grey”>

<pre>

<?xml version="1.0"?>

<config>

 <modules>

 <Auriga_Editable>

 <version>0.1.0</version>

 </Auriga_Editable>

 </modules>

 <global>

 <models>

 <editable>

 <class>Auriga_Editable_Model</class>

 </editable>

 </models>

 <blocks>

 <editable>

 <class>Auriga_Editable_Block</class>

 </editable>

 </blocks>

 <helpers>

 <editable>

 <class>Auriga_Editable_Helper</class>

 </editable>

 </helpers>

 </global>

 <admin>

<routers>

 <editable>

 <use>admin</use>

<args>

 <module>Auriga_Editable</module>

 <frontName>editable</frontName>

</args>

 </editable>

</routers>

 </admin>

 <adminhtml>

 <events>

 <core_block_abstract_prepare_layout_after>

 <observers>

 <addColumnToGrid>

 <type>model</type>

 <class>Auriga_Editable_Model_Observer</class>

 <method>core_block_abstract_prepare_layout_after</method>

 </addColumnToGrid>

 </observers>

 </core_block_abstract_prepare_layout_after>

 <core_block_abstract_prepare_layout_after>

 <observers>

 <addColumnToGridJs>

 <type>model</type>

 <class>Auriga_Editable_Model_Observer</class>

 <method>core_block_abstract_prepare_layout_after_javascript_init</method>

 </addColumnToGridJs>

 </observers>

 </core_block_abstract_prepare_layout_after>

 </events>

 </adminhtml>

 </config>

</pre>

</div>

Step 3 : create a blank helper class

app/code/local/Auriga/Editable/Helper/Data.php

<div style=”color:white;background-color:grey; overflow:auto”>

<pre>

 <?php

 class Auriga_Editable_Helper_Data extends Mage_Core_Helper_Abstract

 {

 }

</pre>

</div>

Step 4 : create a observer to add column in the grid and to add a JS also

app/code/local/Auriga/Editable/Model/Observer.php

<div style=”color:white;background-color:grey”>

<pre>

<?php

class Auriga_Editable_Model_Observer

{

 public function core_block_abstract_prepare_layout_after_javascript_init($observer)

 {

 $block = $observer->getEvent()->getBlock();

 if (in_array($block->getRequest()->getControllerName(), $this->getControllerNames())) {

 if ($block instanceof Mage_Adminhtml_Block_Widget_Grid && $block->getId() 

== 'productGrid') {

 // Load required javascript grid modification.

 if ($block->getLayout()->getBlock('head')) {

 $block->getLayout()->getBlock('head')->addJs('editable/adminhtml_grid.js');

 }

 }

 }

 }

 public function core_block_abstract_prepare_layout_after($observer)

 {

 $block = $observer->getEvent()->getBlock();

 if (in_array($block->getRequest()->getControllerName(), $this->getControllerNames())) {

 $isSecure = Mage::app()->getStore()->isCurrentlySecure() ? true : false;

 if ($block instanceof Mage_Adminhtml_Block_Widget_Grid && $block->getId() 

== 'productGrid') {

 // Add column to grid

 $block->addColumn(

 'change_qty',

 array('header' => Mage::helper('editable')->__('Quantity'),

 'type' => 'text',

 'sortable' => false,

 'renderer' => 'Auriga_Editable_Block_Adminhtml_Renderer_Quantity',

 'filter' => 'Auriga_Editable_Block_Adminhtml_Renderer_Quantity',

 'width' => 190)

 );

 } 

 }

 }

 public function getControllerNames()

 {

 return array( 'adminhtml_catalog_product', 'catalog_product');

 }

}

?>

</pre>

</div>

//In the above two funtion I have placed 2 condition. One is for controller and other is for product grid. This is because I am adding JS file on the product listing page only so in getControllerName() function I only added product controller and used “productGrid” which is the ID of the product listing grid. If you are modifying any other grid then change these 2 condition accordingly.

Step 5 : Create a renderer to get input field in column

app/code/local/Auriga/Editable/Block/Adminhtml/Renderer/Quantity.php

<div style=”color:white;background-color:grey; overflow:auto”>

<pre>

<?php 

class Auriga_Editable_Block_Adminhtml_Renderer_Quantity extends 

Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Select

{

 public function render(Varien_Object $row)

 {

 $colId = 'qty';

 $productId = $row->getEntityId();

 $product=Mage::getModel('catalog/product')->load($productId);

 $html = '<input name="' . $colId . '-' . $row->getId() . '" rel="' . $row->getId() . '" 

class="input-text ' . $colId . '"

 value="' . (int) $product->stockItem->getQty() . '" style="width:97%;" />';

 return $html;

 }

}

?>

</pre>

</div>


Step 6 : create JS file which will add input field value in the form to send it to the controller.

js/ editable/adminhtml_grid.js

<div style=”color:white;background-color:grey; overflow:auto”>

<pre>

 var varienGridMassaction = Class.create(varienGridMassaction, {

 apply:function ($super) {

 var qties = [];

 $('productGrid_table').getElementsBySelector('.qty').each(function (qty) {

 if(qty.value!='')

 {

 qties.push(qty.readAttribute('rel') + '[|]' + qty.value);

 }

 });

 new Insertion.Bottom(this.formAdditional, this.fieldTemplate.evaluate({name:'qties', 

value:qties}));

 return $super();

 }

});

</pre>

</div>

Step 7 : Last step is to get the post data at the controller and perform action accordingly. Copy this function and paste this in your controller.

<div style=”color:white;background-color:grey; overflow:auto”>

<pre>

 Public function getQty()

 {

 $qtyies=explode(",", Mage::app()->getRequest()->getPost('qties', false));

 foreach ($qtyies as $rawQty) {

 if ($rawQty == '') {

 continue;

 }

 list($productId, $qty) = explode("[|]", $rawQty);

 if (!empty($productId)) {

 $qtyArray[$productId] = $qty;

 }

 }

 return $qtyArray;

 } 

</pre>

</div>

This function will return an array which has quantity value for each product. So you have to get value of each product which get selected through Grid. To update the quantity of products,let’s add a action in massaction dropdown and write code for that.

Add following code in the observer in core_block_abstract_prepare_layout_after function

after if ($block instanceof Mage_Adminhtml_Block_Widget_Grid && $block->getId() 

== 'productGrid')

{

}

<div style=”color:white;background-color:grey; overflow:auto”>

<pre>

if ($block instanceof Mage_Adminhtml_Block_Widget_Grid_Massaction && 

in_array($block->getRequest()->getControllerName(), $this->getControllerNames()))

 {

$block->addItem('mass_qty_update', array(

 'label' => Mage::helper('core')->__('Update Quantity'),

 'url' => Mage::app()->getStore()->getUrl('*/editable/massQtyUpdate', 

array('actions' =>'mass_qty_update', '_secure' => $isSecure))

 ));

 }

</pre>

</div>


Now we have to create a controller which will get our post data and update the quantity.

Create app/code/local/Auriga/Editable/controllers/Adminhtml/EditableController.php

<div style=”color:white;background-color:grey; overflow:auto”>

<pre>

<?php

class Auriga_Editable_Adminhtml_EditableController extends 

Mage_Adminhtml_Controller_Action

{

 public function massQtyUpdateAction()

 {

$productIds = $this->getRequest()->getParam('product');

$qtyArray=$this->getQty();

if (!is_array($productIds)) {

 $this->_getSession()->addError($this->__('Please select product(s).'));

 } else {

 if (!empty($productIds)) {

 try {

 foreach ($productIds as $productId) {

if($qtyArray[$productId]){

 $product = Mage::getSingleton('catalog/product')->load($productId);

$stockData['qty'] =$qtyArray[$productId];

 $product->setStockData($stockData);

 $product->save();

}

 }

 $this->_getSession()->addSuccess(

 $this->__('Total of %d record(s) have been updated.', count($productIds))

 );

 } catch (Exception $e) {

 $this->_getSession()->addError($e->getMessage());

 }

 }

 }

$this->_redirect('/catalog_product/index');

 }

 Public function getQty()

 {

 $qtyies=explode(",", Mage::app()->getRequest()->getPost('qties', false));

 foreach ($qtyies as $rawQty) {

 if ($rawQty == '') {

 continue;

 }

 list($productId, $qty) = explode("[|]", $rawQty);

 if (!empty($productId)) {

 $qtyArray[$productId] = $qty;

 }

 }

 return $qtyArray;

 } 

}

</pre>

</div>

So in this way you can add column with input fields in the grid and send information to the controller to perform actions accordingly. The main thing in this tutorial is the JS file which add the input field in the form.

Please provide us the feedback for any suggestion and improvement.

Related content

We Love Conversations

Say Hello
Go to Top