Zend Framework and prototype: Creating nice grid having ajax functionality

26 Feb

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.

Zend framework grid

Zend framework grid

 After clicking edit you would see grid like the following.

Zend Framework grid in edit mode

Zend Framework grid in edit mode

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.

One Response to “Zend Framework and prototype: Creating nice grid having ajax functionality”

  1. elmo February 26, 2009 at 7:14 pm #

    I’m sorry if I sound rude, you got me interested in your results, but so far this post only says that at the end of this tutorial I will see a grid like…(end of post)

    Am I missing something here, or should I consider this post to be a work in progress? Once again, I do not intend to be rude or impatient. I’m rather curious about why I’m missing the actual tutorial part of this post.

    Keep up the good work

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: