The old way to make a grid was very time consuming. Basically it is just copy paste but still there is a lot to rewrite. You have to take care of the actions, pager and maybe a filter.
So i tried ext js grid. Since extjs renders the grid alone and looks a lot better then my grids which are done with smarty, html table and css.
A good grid should
- Paginate
- Filter
- Sort
- Edit ??? (maybe)
To make an extjs grid you need 3 pieces of code. Store, Columns and the Grid its self. Since Zend framework DB model component has some information we can use, I tried to automate a piece of it.
Not to forget, you have to create models for the tables that you want to use. The extended zend_db_table will create a .js file for us which includes the store and the columns model for our grid. After the file is created we can manually edit and change it to fit our needs, like hiding some columns or different formating.
The Store
I also extended the zend_db_rowset to return json data for its rowset, so i do use the Ext.data.JsonStore. it looks like this.
var xmlStore = new Ext.data.JsonStore({
url: '/some/index/xml-list/', // here we have an action in some module, index controller
fields: xml_st, // created via zend_db_table
totalProperty: 'count', // calculated from zend_db_table
root: 'xml' // allways the table name, xml here is not the output format!!!
});
Now the created fields from zend_db_table. Also not to forget we have to include the created files from zend_db_table.
// this is created from zend_db_table.
var xml_st = [
{name: 'xml_id', type: 'int'},
{name: 'created_on', type: 'date', dateFormat: 'Y-m-d H:i:s'},
{name: 'updated_on', type: 'date', dateFormat: 'Y-m-d H:i:s'},
{name: 'xml_name', type: 'string'},
{name: 'xml_description', type: 'string'},
{name: 'status', type: 'int'}
];
Because we have the information of the field from mysql and zend_db_table we can create this file. So if you would need some more improvement you could edit the created file and add some more meta data.
The Column Model
We can also create some basic information about the columns with the meta data from mysql for the table.
// this is created from zend_db_table
var xml_cm = [
{header: 'xml_id', dataIndex: 'xml_id', id: 'xml_id', resizeable: true, sortable: true, align: 'right'},
{header: 'created_on', dataIndex: 'created_on', id: 'created_on', resizeable: true, sortable: true, renderer: Ext.util.Format.dateRenderer('d.m.Y')},
{header: 'updated_on', dataIndex: 'updated_on', id: 'updated_on', resizeable: true, sortable: true, renderer: Ext.util.Format.dateRenderer('d.m.Y')},
{header: 'xml_name', dataIndex: 'xml_name', id: 'xml_name', resizeable: true, sortable: true},
{header: 'xml_description', dataIndex: 'xml_description', id: 'xml_description', resizeable: true, sortable: true},
{header: 'status', dataIndex: 'status', id: 'status', resizeable: true, sortable: true, hidden: true}
];
In this example i added the information about hidden:true. You can still change some other setting.
The Grid
// this is all we have to write to make a basic grid
var xmlGrid = new Ext.grid.GridPanel({
renderTo: 'xml_div',
title: 'XML',
store: xmlStore,
columns: xml_cm, // the created column model
stripeRows: true,
border: true,
frame: true
});
So this would be the basic grid. in next series we also are going to add the pager, grouping, filter and maybe some other stuff and demonstrate how it work together with zend_framework.
The PHP Part
This is the basic extend for the zend_db_table. If you do not want to use this class you can use (copy & paste) the code. I do not need any credits.
We have here to function one of them is getCount(). This function hepls us to get the count for the rowset object and the information is also used for the pager.
extWriteGridSettings(), will write a .js file for its model. So if you have a model called xml it will write xml_gs.js to the folder which you set (GridSettings).
getAdapter()->fetchOne("select count(*) as count from {$this->_name} where $where");
} else {
$count = $this->getAdapter()->fetchOne("select count(*) as count from {$this->_name}");
}
return $count;
}
public function extWriteGridSettings() // write some settings
{
$cm = "var {$this->_name}_cm = [\n";
$st = "var {$this->_name}_st = [\n";
foreach($this->_metadata as $index => $arr) { // the metadata
switch($arr['DATA_TYPE']) {
case 'int':
$type = 'int';
$cmExtra = ", align: 'right'";
break;
case 'mediumint':
$type = 'int';
$cmExtra = ", align: 'right'";
break;
case 'timestamp':
$type = 'date';
$stExtra = ", dateFormat: 'Y-m-d H:i:s'";
$cmExtra = ", renderer: Ext.util.Format.dateRenderer('d.m.Y')";
break;
case 'decimal':
$type = 'auto';
$cmExtra = ", align: 'right', renderer: Ext.util.Format.Currency";
break;
case 'varchar':
$type = 'string';
break;
case 'tinyint':
$type = 'int';
break;
case 'text':
$type = 'string';
break;
default:
$type = 'auto';
break;
}
if(strlen($this->sortables[$index]) > 0) {
$cmArr[] = "\n\t{header: '{$this->sortables[$index]}', dataIndex: '$index', id: '$index', resizeable: true, sortable: true{$cmExtra}}";
} else {
$cmArr[] = "\n\t{header: '$index', dataIndex: '$index', id: '$index', resizeable: true, sortable: true{$cmExtra}}";
}
$stArr[] = "\n\t{name: '$index', type: '$type'$stExtra}";
$type = '';
$stExtra = '';
$cmExtra = '';
}
$cm .= implode(', ', $cmArr)."\n\n];\n\n";
$st .= implode(', ', $stArr)."\n\n];";
$cf = Zend_Registry::get('config');
$fp = fopen($cf->path->file.'pub/js/ext-cache/'.$this->_name.'_gs.js', 'a'); // write where ever you wish
fwrite($fp, $cm.$st);
fclose($fp);
chmod($cf->path->file.'pub/js/ext-cache/'.$this->_name.'_gs.js', 0777);
}
}
All of my models extend the reverse_db_table so i have always the functions. Just use once $model->extWriteGridSettings(); and it will write it do disk.
Now the row set extend.
_table->getCount($where);
$count = 0;
foreach($this->_data as $key => $value) {
$arr[$this->_table->info('name')][$count] = $value;
$count++;
}
if($count == 0) {
$arr[$this->_table->info('name')];
}
return Zend_Json::encode($arr);
}
}
Now some usage examples.
public function xmlListAction()
{
$this->_autoRender = false; // my internal funciton to stop smarty from rendering
$xmlModel = new xmls(); // the model
$rs = $xmlModel->fetchAll();
echo $rs->toExtJson(); // the record set
}
This is a simple action in zend_controller.
Thats it for today. I am very sorry of my English and writing skills but i will answer the comment (maybe 🙂 ).
Hi,
it’s a great tutorial! Could make some more? for example about how to configure extjs with Zend Framework? thanx in advance!
I’d consider to put that into your Zend library to make ExtJS quickly available from your views.
Well that’s how I solved it…