Few weeks back I tried to make a dojo grid. Though I successfully created one with the sorting functionality but didn’t succeeded in making that gird editable.
Yesterday I decided why not make a grid using some javascript and prototype library for providing on the fly editing functionality.
So here I am with a nice and cool grid with everything working.
At the end of this tutorial you will see a grid like.
After clicking edit you would see grid like the following.
The grid now provide two options, save and cancel. If you click the save button the contents will be saved on the fly with AJAX request. However if you click the cancel, the grid will go back to its previous un editable format.
Before going to discuss how to get this functionality I would like to tell you that if you haven’t read my previous post on making grid using Zend Framework, please read that. If haven’t read that article you will not be able to understand this tutorial.
In my previous post I created a grid by creating my own view helper as
<?php
require_once ‘Zend/View/Helper/Abstract.php’;
class Zend_View_Helper_Grid2 extends Zend_View_Helper_Abstract
{
public $sorting=null;
public $view = null;
public function setView(Zend_View_Interface $view)
{
$this->view = $view;
return $this;
}
public function grid2($name, $fields = null,$paginator=null,$sorting=false)
{
$sort = Zend_Controller_Front::getInstance()->getRequest()->getParam(’sort’,'DESC’);
if($sort == ‘ASC’) {
$sort = ‘DESC’;
} else {
$sort = “ASC”;
}
$output=”<div id=’”.$name.”‘>”;
$output .= “<table class=’grid’>
<thead>
<tr>”;
foreach($fields as $key=>$value) {
$output .= “<th>”;
if ($sorting){
$output .= “<a href=’”.
$this->view->url(array(’sort’=>$sort,’by’=>$key)).”‘>”.$value.”</a>”;
} else {
$output .= $value;
}
$output .= “</th>”;
}
$output .= “</tr></thead>”;
$output .=”<tbody>”;
foreach($paginator as $p) {
$output.=”<tr id=’row”.$p['id'].”‘>”;
foreach($p as $record) {
$output .= “<td>”.$record.”</td>”;
}
$output .=”<td id=’action”.$p['id'].”‘><a href=’#’
onclick=’edit(“.$p['id'].”)’>Edit<a></td>”;
$output.=”</tr>”;
}
$output .= “</tbody>”;
if($paginator) {
$output .=”<tfoot>”;
$output .=”<td align=’center’ colspan=’”.count($fields).”‘>”;
$output.= $this->view->paginationControl($paginator,
’Sliding’,
‘pagination.phtml’);
$output .=”</tfoot>”;
}
$output .=”</table><div>”;
return $output;
}
}
The only difference between my previous helper and this helper is
$output .=”<td id=’action”.$p['id'].”‘><a href=’#’
onclick=’edit(“.$p['id'].”)’>Edit<a></td>”;
If you look at the code you will understand that I have added extra “td” for making edit link and I have associated onclick event to the link. When you click on the link the edit javascript function is called.
Sorry I forgot one thing. I also associated id with the row attribute as
$output.=”<tr id=’row”.$p['id'].”‘>”;
Now as we have defined our view helper, its now time to edit our view template. We make the following modifications to our view template.
<?
$fields = array(
‘id’ => ‘ID’,
‘firstname’ => ‘First Name’,
‘lastname’ => ‘Last Name’,
‘email’ => ‘Email’,
‘username’ =>’Username’,
‘edit’ => ‘Action’
);
echo $this->grid2(
‘grd’,
$fields,
$this->paginator,
true);
?>
If you compare this with the previous one, you will find that we have only added Action string to our field array.
However the most important thing in creating this gird is javascript code
The javascript I have defined look as
<script>
var editable=true;
function edit(id)
{
var row=$(“row” + id);
var cells=row.getElementsByTagName(“td”);
if(editable) {
cells[0].innerHTML=”<input type=’text’ name=’Id’ id=’Id’ value=’”+ cells[0].innerHTML +”‘ size=’5′/>”;
cells[1].innerHTML=”<input type=’text’ id=’firstname’ name=’firstname’ value=’”+ cells[1].innerHTML +”‘ size=’15′ />”;
cells[2].innerHTML=”<input type=’text’ id=’lastname’ name=’lastname’ value=’”+ cells[2].innerHTML +”‘ size=’15′ />”;
cells[3].innerHTML=”<input type=’text’ id=’email’ name=’email’ value=’”+ cells[3].innerHTML +”‘ size=’15′ />”;
cells[4].innerHTML=”<input type=’text’ id=’username’ name=’username’ value=’”+ cells[4].innerHTML +”‘ size=’15′ />”;
cells[5].innerHTML=”<a href=’javascript:#’ onClick=’save()’>Save</a>”
+”<br /><a href=’javascript:#’ onClick=’edit(” + id + “)’>Cancel</a>”;
editable=false;
} else {
cells[0].innerHTML=$(‘Id’).value;
cells[1].innerHTML=$(‘firstname’).value;
cells[2].innerHTML=$(‘lastname’).value;
cells[3].innerHTML=$(‘email’).value;
cells[4].innerHTML=$(‘username’).value;
cells[5].innerHTML=”<a href=’javascript:#’ onClick=’edit(” + id + “)’>Edit</a>”;
editable=true;
}
}
function save()
{
new Ajax.Request(
“<?=$this->url(array(‘action’=>’save’))?>”, { method: ‘get’,
parameters: {Id: $(‘Id’).value, firstname:$(‘firstname’).value,
lastname:$(‘lastname’).value, email:$(‘email’).value, username:$(‘username’).value
}
});
}
</script>
Nothing hard to understand.
In our edit method, we first get reference to our row element. And then call getElementByTagName java script method to get reference to all td elements of the row.
We then add input box to each td and give the value of the td to that input box.
The if condition specify that if we are not in editable mode, if condition is executed and we are taken to the edit mode otherwise we are taken back to the un editable condition.
In the save method we make an ajax call using prototype Ajax request object.
Giving this method the url and the params.
In our controller saveAction we will have code like this.
public function saveAction()
{
$users = new Users();
$id = $this->_getParam(‘Id’);
$data['firstname'] = $this->_getParam(‘firstname’);
$data['lastname'] = $this->_getParam(‘lastname’);
$data['email'] = $this->_getParam(‘email’);
$data['username'] = $this->_getParam(‘username’);
$users->update($data,’id=’.$id);
exit;
}
In the action User is our model. we get reference to our model then get params using _getParam() method, give these values to the update method.
And that’s it we are done.




