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

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);




























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.
admin said,
Wrote on August 14, 2008 @ 8:29 am
I’ve already fix it, thanks
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
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
Pankaj said,
Wrote on December 4, 2008 @ 6:51 pm
where to put this javascript code (in which directry )
ianemv said,
Wrote on December 21, 2008 @ 11:56 am
Interesting..Gonna try this later.
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?
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
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.