CakePHP and ExtJS EditorGridPanel

Here’s another basic tutorial combining CakePHP and ExtJS, this time using grid editor. For this tutorial I assume that you have the basic knowledge cakephp, using bake utilities.
here’s the online demo

Grid Editor

table we need, based on my previous tutorial

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) NOT NULL DEFAULT '',
  `password` varchar(255) NOT NULL,
  `firstname` varchar(255) NOT NULL,
  `lastname` varchar(255) NOT NULL,
  `email` varchar(255) NOT NULL,
  `gender` enum('Male','Female') NOT NULL DEFAULT 'Male',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=latin1

than using bake utilities create the model, controller and the view.
here’s my Users controllers :

class UsersController extends AppController {
 
var $name = 'Users';
	var $helpers = array('Html', 'Form', 'Javascript');
	var $components = array('RequestHandler');
 
	function index() {
		if($this->RequestHandler->isAjax()) {
			//$this->User->recursive = 0;
			$this->layout = 'Ajax';
			$count = $this->User->find('count');
			$dump  = $this->User->find('all');
			$users = Set::extract($dump, '{n}.User');
 
			$this->set('total', $count);
			$this->set('users',$users);
		} else {
 
		}
	}
 
	function add() {
		$this->layout = 'Ajax';
 
		if (!empty($this->data)) {
			$this->User->create();
			if ($this->User->save($this->data)) {
				$this->set('success', '{success:true}');
			} else {
				$this->set('success', '{success:false}');
			}
		}
	}
 
	function edit($id = null) {
		$this->layout = 'Ajax';
 
		if (!$id && empty($this->data)) {
			$this->set('success', '{success:false}');
		}
		if (!empty($this->data)) {
			if ($this->User->save($this->data)) {
				$this->set('success', '{success:true}');
			} else {
				$this->set('success', '{success:false}');
			}
		}
 
	}
 
	function delete($id = null) {
		$this->layout = 'Ajax';
		if($this->RequestHandler->isAjax()) {
			if (!$id) {
				$this->set('success', '{success:false}');
			}
			if ($this->User->del($id)) {
				$this->set('success', '{success:true}');
			}
		}
	}
 
}

then index.ctp view would be

<?php
	if(isset($total) and isset($users)) {
		echo '{"total":'.$total.', "users":'.$javascript->Object($users).'}';
	} else {
 
 
?>
<select name="gender" id="gender" style="display:none;">
	<option value="Male">Male</option>
	<option value="Female">Female</option>
</select>
 
<form id="submitgrid"></form>
 
<div id="usergrid" style="overflow: hidden;"></div>
 
<?php
	}
?>

last the javascript code

Ext.BLANK_IMAGE_URL = '/kelinci/css/extjs/images/default/s.gif';
 
var UGrid = function () {
	var userDS;
	var userCM;
	var userGrid;
 
	function setDS() {
		userDS = new Ext.data.JsonStore({
			url: '/kelinci/users/getUserList',
			root: 'users',
			id: 'id',
			totalProperty: 'total',
			fields: ['id','username','password','firstname','lastname','email','gender']
		})
		userDS.load();
	}
 
	function getColModel() {
		userCM = new Ext.grid.ColumnModel(
			[
				new Ext.grid.RowNumberer(),
				{
					header: 'id',
					hidden: true,
					width: 30,
					sortable: true,
					dataIndex: 'id'
				},
				{
					header: 'Username',
					hidden: false,
					width: 120,
					sortable: true,
					dataIndex: 'username',
					editor: new Ext.grid.GridEditor(
							new Ext.form.TextField(
							 	{
									allowBlank: false
								}
							)
					)
				},
				{
					header: 'Password',
					hidden: false,
					width: 120,
					sortable: true,
					dataIndex: 'password',
					editor: new Ext.grid.GridEditor(
							new Ext.form.TextField(
							 	{
									allowBlank: false
								}
							)
					)
				},
				{
					header: 'First Name',
					hidden: false,
					width: 120,
					sortable: true,
					dataIndex: 'firstname',
					editor: new Ext.grid.GridEditor(
							new Ext.form.TextField(
							 	{
									allowBlank: false
								}
							)
					)
				},
				{
					header: 'Last Name',
					hidden: false,
					width: 120,
					sortable: true,
					dataIndex: 'lastname',
					editor: new Ext.grid.GridEditor(
							new Ext.form.TextField(
							 	{
									allowBlank: false
								}
							)
					)
				},
				{
					header: 'Email',
					hidden: false,
					width: 100,
					sortable: true,
					dataIndex: 'email',
					editor: new Ext.grid.GridEditor(
							new Ext.form.TextField(
							 	{
									allowBlank: false
								}
							)
					)
				},
				{
					header: 'Gender',
					hidden: false,
					width: 50,
					sortable: true,
					dataIndex: 'gender',
					editor: new Ext.grid.GridEditor(
						new Ext.form.ComboBox(
						 	{
								typeAhead:true,
								triggerAction:'all',
								lazyRender:true,
								transform:'gender'
							}
						)
					)
				}
			]
		);
 
		return userCM;
	}
 
	function createGrid() {
		userCM = getColModel();
		userGrid = new Ext.grid.EditorGridPanel(
			{
				renderTo: 'usergrid',
				title: 'Grid Editor with CakePHP',
				ds: userDS,
				cm: userCM,
				autoSizeColumns: true,
				stripeRows: true,
				loadMask: true,
				width: 700,
				height: 300,
				selModel: new Ext.grid.RowSelectionModel({singleSelect:true}),
				viewConfig: {
	        		forceFit:true
	    		},
				tbar:
				[
				{
	        		text:'Add',
	        		tooltip:'Add new user',
	        		iconCls:'add',
	        		handler: function() {
	        			var gridForm = new Ext.BasicForm(
							Ext.get("submitgrid"),
							{
								baseParams: {
									'data[User][username]': 'username',
									'data[User][password]':'password',
									'data[User][firstname]': 'firstname',
									'data[User][lastname]': 'lastname',
									'data[User][email]':'user@email.com',
									'data[User][gender]':'Male'
								},
								url:'/kelinci/users/add'
							}
						);
 
						gridForm.submit(
							{
								waitMsg: 'Saving, please wait...',
 
								success:function(form, action) {
									Ext.Msg.alert('Status', 'Add new record saved successfully.');
									userDS.load();
								},
								failure: function(form, action) {
									Ext.Msg.alert('Status', 'Add new record failed.');
								}
							}
						);
 
	        		}
	    		},
				{
					text:'Remove',
	        		tooltip:'Delete  user',
	        		iconCls:'remove',
					handler: function() {
            			var hd = userGrid.getSelectionModel().getSelected().data;
						if (hd) {
            				Ext.MessageBox.confirm('Confirm', 'Are you sure you want to do that?',
            				function(btn) {
            					if(btn == 'yes') {
									Ext.MessageBox.show({
									   title: 'Please wait',
							           msg: 'Deleting...',
							           progressText: 'Deleting User ...',
							           width:300,
							           progress:true,
							           closable:false
							        });
            						Ext.Ajax.request({
										url: '/kelinci/users/delete/'+hd.id,
										success:function() {
											Ext.MessageBox.hide();
								   			Ext.Msg.alert('Status','Config deleted succesfuly ');
								   			userDS.load();
								   		},
  										failure: function() {
											Ext.MessageBox.hide();
  											Ext.Msg.alert('Status','Oops something wrong with server ??');
  										}
 
									});
 
									//Ext.Ajax.on('beforerequest', this.showSpinner, this);
            					}
            				}
            				);
						}
					}
				}
				]
 
			}
 
		);
 
		userGrid.on({
			afteredit: function(e) {
 
				Ext.Ajax.request({
 
					url: '/kelinci/users/edit/'+e.record.data['id'],
					method: 'POST',
					params: {
						'data[User][id]': e.record.data['id'],
						'data[User][username]': e.record.data['username'],
						'data[User][password]': e.record.data['password'],
						'data[User][firstname]': e.record.data['firstname'],
						'data[User][lastname]': e.record.data['lastname'],
 
						'data[User][email]': e.record.data['email'],
						'data[User][gender]':e.record.data['gender']
					},
					success:function() {
			   			//userDS.load();
			   		},
					failure: function() {
						//
					}
 
				});
 
				//console.log('e.record.data[\'id\'] = ' + e.record.data['id']);
 
		  	}
		});
	}
 
	return {
		init : function () {
			setDS();
			createGrid();
		},
		getDS : function () {
			return userDS;
		}
	}
}();
 
Ext.onReady(UGrid.init, UGrid, true);

9 Comments so far »

  1. Nice Example said,

    Wrote on August 14, 2008 @ 4:04 am

    Nice example. The only thing is that the “>” is encoded making it difficult to copy & paste.

  2. admin said,

    Wrote on August 14, 2008 @ 8:29 am

    I’ve already fix it, thanks

  3. ramiro said,

    Wrote on October 8, 2008 @ 10:07 pm

    Buen ejemmplo, sencillo… pero falta la función “getUserList” del controlador…. y no carga datos, ¿Cómo puedo hacerlo?
    atte.
    ramiro

    postdata.- muchas gracias por la colaboracion

  4. endy said,

    Wrote on October 9, 2008 @ 2:56 am

    @ramiro
    my mistake ^_^Y, getUserList => index function

    userDS = new Ext.data.JsonStore({
    url: ‘/kelinci/users/index’,
    root: ‘users’,
    id: ‘id’,
    totalProperty: ‘total’,
    fields: ['id','username','password','firstname','lastname','email','gender']
    })
    userDS.load();

    thanks

  5. Pankaj said,

    Wrote on December 4, 2008 @ 6:51 pm

    where to put this javascript code (in which directry )

  6. ianemv said,

    Wrote on December 21, 2008 @ 11:56 am

    Interesting..Gonna try this later.

  7. Ianemv said,

    Wrote on December 23, 2008 @ 3:44 pm

    Noticed that when i add record, it would still output failure and yet data is already added to the database. Same case with the delete option, data is deleted but it’s still failure.

    Any comments?

  8. admin said,

    Wrote on December 23, 2008 @ 3:54 pm

    @lanemv: you can debug the value returned by add, delete function on with firebug it should returning ‘{success:true}’ in json format

  9. ianemv said,

    Wrote on December 23, 2008 @ 6:58 pm

    got it working already.

    you forgot to mentioned that we have to create a add.ctp and delete.ctp to display the ‘{success:}’ result.

Comment RSS · TrackBack URI

Leave a Comment

Name: (Required)

E-mail: (Required)

Website:

Comment: