One more step in CakePHP towards extJs with JSON

So, here is another full example, just like my other CakePHP + extJS, but this one is using JSON rather then XML.

The XML version of this example is available here.

So, first load the stylesheets, and javascripts in the default.thtml:

<?php echo $html->css('../js/ext/resources/css/ext-all');?>
<?php echo $html->css('cake.generic');?>
<?php echo $javascript->link('ext/adapter/ext/ext-base.js');?>
<?php echo $javascript->link('ext/ext-all.js');?>
<?php echo $javascript->link('RowExpander.js');?>
<?php echo $javascript->link("$_name-$_action.js");?>

Assign, the controller’s name, and the function name, as view variables, in app/app_controller.php like this:

function beforeRender()
{
	$this->set('_name',strtolower($this->name));
	$this->set('_action',strtolower($this->action));
}

Now I need to copy the ext library to /app/webroot/js/ext, and create the /app/webroot/js/posts-index.js there.

My posts-index.js contains this:

/*
 * Ext JS Library 2.0
 * Copyright(c) 2006-2007, Ext JS, LLC.
 * licensing@extjs.com
 *
 * http://extjs.com/license
 */
 
Ext.onReady(function(){
 
    Ext.QuickTips.init();
 
    var xg = Ext.grid;
 
    // create the Data Store
    // create the Data Store
    var store = new Ext.data.Store
	({
        // load using HTTP
		proxy: new Ext.data.HttpProxy({url: '/posts/json'}),
		reader : new Ext.data.JsonReader
		({
			id: 'id'
	    },
		[
			{name: 'id', type: 'int'},
			{name: 'title', type: 'string'},
	        {name: 'body', type: 'string'},
	        {name: 'created', type: 'date', dateFormat:'Y-m-d H:i:s'},
			{name: 'modified', type: 'date', dateFormat:'Y-m-d H:i:s'}
	    ])
    });	
 
	// expander cucc
	var expander = new xg.RowExpander({
		tpl : new Ext.Template(
			'<b>Body:</b>',
            '
 
{body}
 
'
        )
    });	
 
    var sm = new xg.CheckboxSelectionModel();
    var grid = new xg.GridPanel({
        id:'button-grid',
        store: store,
        cm: new xg.ColumnModel([
			expander,
            sm,
            {header: "Id", width: 5, sortable: true, dataIndex: 'id'},
            {header: "Title", width: 20, sortable: true, dataIndex: 'title'},
			{header: "Created", width: 20, sortable: true, dataIndex: 'created', renderer: Ext.util.Format.dateRenderer('Y-m-d H:i:s')},
            {header: "Last Updated", width: 20, sortable: true, dataIndex: 'modified', renderer: Ext.util.Format.dateRenderer('Y-m-d H:i:s')}
        ]),
        sm: sm,
 
        viewConfig: {
            forceFit:true
        },
 
        // inline buttons
        buttons: [{text:'Save'},{text:'Cancel'}],
        buttonAlign:'center',
 
        // inline toolbars
        tbar:[{
            text:'Add Post',
            tooltip:'Add a new post',
		    handler: function()
			{
				location.href='/posts/add';
			},
            iconCls:'add'
        }],
		plugins: expander,
        width:600,
        height:300,
        frame:true,
        title:'Posts',
        iconCls:'icon-grid',
        renderTo:'content'
    });
 
    store.load();
});

Please notice the “url” attribute in line 18. It refers to /posts/json, so I need to create a controller function, a view, and a separate layout for that.

So I create the json object processing function in the posts_controller.php:

function json()
{
	$this->layout='json';
 
	foreach ($this->Post->findAll() as $post)
	{
		$o[] = $post['Post'];
	}
 
	$this->set('data',json_encode($o));
}

As you see, we need a layout for that, so I’ll create it a json.thtml in ‘/app/views/layouts/’, what contains this:

<?php
echo $content_for_layout;
?>

After this I need to create the view called ‘json.thtml’ in the ‘app/views/posts’, as well.
As you might see, we have a variable called ‘data’, that will contain, the json object.
So we only need to echo it in the view:

<?php echo $data; ?>

We are almost ready now.
You need to truncate your posts/index.thtml because extJs will render everything in the “content” div (where the views rendered generaly), so it’s better, to be blank.

There’s only more thing left. We need ‘RowExpander.js’ from the ‘ext/examples/grid’ directory. So we need to copy it to /js directory.

The XML version of this example is available here.

“One more step in CakePHP towards extJs with JSON” bejegyzéshez 3 hozzászólás

  1. function json()
    {
    $this->layout=’json’;

    foreach ($this->Post->findAll() as $post)
    {
    $o[] = $post[‘Post’];
    }

    $this->set(‘data’,json_encode($o));
    }

    Instead of doing the foreach loop you can do this way
    $o = Set::extract($this->Post->findAll(), ‘{n}.Post’ );
    $this->set(‘data’, $o);

    Then in the json.thtml Layout you can do the encoding

  2. Thank you, for that Boris.
    I don’t do it in the view, because I use it together with Smarty, and as you know, it can’t run real PHP code, only custom functions 🙂

  3. Nice tutorial. It gave me a light way to access extjs in cake php.
    But a problem puzzling me for a long time is how to update/delete back to database?

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöljük.