Zend Framework & ExtJS Grid - part 1

All, Extjs, Javascript, PHP, Zend Framework

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.

JAVASCRIPT [Show Plain Code]:
  1. var xmlStore = new Ext.data.JsonStore({
  2.         url: ‘/some/index/xml-list/’, // here we have an action in some module, index controller
  3.         fields: xml_st, // created via zend_db_table
  4.         totalProperty: ‘count’, // calculated from zend_db_table
  5.         root: ‘xml’ // allways the table name, xml here is not the output format!!!
  6. });

Now the created fields from zend_db_table. Also not to forget we have to include the created files from zend_db_table.

JAVASCRIPT [Show Plain Code]:
  1. // this is created from zend_db_table.
  2. var xml_st = [
  3.         {name: ‘xml_id’, type: ‘int’},
  4.         {name: ‘created_on’, type: ‘date’, dateFormat: ‘Y-m-d H:i:s’},
  5.         {name: ‘updated_on’, type: ‘date’, dateFormat: ‘Y-m-d H:i:s’},
  6.         {name: ‘xml_name’, type: ’string’},
  7.         {name: ‘xml_description’, type: ’string’},
  8.         {name: ’status’, type: ‘int’}
  9. ];

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.

JAVASCRIPT [Show Plain Code]:
  1. // this is created from zend_db_table
  2. var xml_cm = [
  3.         {header: ‘xml_id’, dataIndex: ‘xml_id’, id: ‘xml_id’, resizeable: true, sortable: true, align: ‘right’},
  4.         {header: ‘created_on’, dataIndex: ‘created_on’, id: ‘created_on’, resizeable: true, sortable: true, renderer: Ext.util.Format.dateRenderer(‘d.m.Y’)},
  5.         {header: ‘updated_on’, dataIndex: ‘updated_on’, id: ‘updated_on’, resizeable: true, sortable: true, renderer: Ext.util.Format.dateRenderer(‘d.m.Y’)},
  6.         {header: ‘xml_name’, dataIndex: ‘xml_name’, id: ‘xml_name’, resizeable: true, sortable: true},
  7.         {header: ‘xml_description’, dataIndex: ‘xml_description’, id: ‘xml_description’, resizeable: true, sortable: true},
  8.         {header: ’status’, dataIndex: ’status’, id: ’status’, resizeable: true, sortable: true, hidden: true}
  9. ];

In this example i added the information about hidden:true. You can still change some other setting.

The Grid

JAVASCRIPT [Show Plain Code]:
  1. // this is all we have to write to make a basic grid
  2. var xmlGrid = new Ext.grid.GridPanel({
  3.         renderTo: ‘xml_div’,
  4.         title: ‘XML’,
  5.         store: xmlStore,
  6.         columns: xml_cm, // the created column model
  7.         stripeRows: true,
  8.         border: true,
  9.         frame: true
  10. });

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

  1. getAdapter()->fetchOne("select count(*) as count from {$this->_name} where $where");
  2.                 } else {
  3.                         $count = $this->getAdapter()->fetchOne("select count(*) as count from {$this->_name}");
  4.                 }
  5.  
  6.                 return $count;
  7.  
  8.         }
  9.  
  10.         public function extWriteGridSettings() // write some settings
  11.         {
  12.  
  13.                 $cm = "var {$this->_name}_cm = [\n";
  14.                 $st = "var {$this->_name}_st = [\n";
  15.  
  16.                 foreach($this->_metadata as $index => $arr) { // the metadata
  17.  
  18.                         switch($arr['DATA_TYPE']) {
  19.                                 case 'int':
  20.                                         $type = 'int';
  21.                                         $cmExtra = ", align: 'right'";
  22.                                         break;
  23.                                 case 'mediumint':
  24.                                         $type = 'int';
  25.                                         $cmExtra = ", align: 'right'";
  26.                                         break;
  27.                                 case 'timestamp':
  28.                                         $type = 'date';
  29.                                         $stExtra = ", dateFormat: 'Y-m-d H:i:s'";
  30.                                         $cmExtra = ", renderer: Ext.util.Format.dateRenderer('d.m.Y')";
  31.                                         break;
  32.                                 case 'decimal':
  33.                                         $type = 'auto';
  34.                                         $cmExtra = ", align: 'right', renderer: Ext.util.Format.Currency";
  35.                                         break;
  36.                                 case 'varchar':
  37.                                         $type = 'string';
  38.                                         break;
  39.                                 case 'tinyint':
  40.                                         $type = 'int';
  41.                                         break;
  42.                                 case 'text':
  43.                                         $type = 'string';
  44.                                         break;
  45.                                 default:
  46.                                         $type = 'auto';
  47.                                         break;
  48.                         }
  49.  
  50.                         if(strlen($this->sortables[$index]) > 0) {
  51.                                 $cmArr[] = "\n\t{header: '{$this->sortables[$index]}’, dataIndex: ‘$index’, id: ‘$index’, resizeable: true, sortable: true{$cmExtra}}";
  52.                         } else {
  53.                                 $cmArr[] = "\n\t{header: ‘$index’, dataIndex: ‘$index’, id: ‘$index’, resizeable: true, sortable: true{$cmExtra}}";
  54.                         }
  55.  
  56.                         $stArr[] = "\n\t{name: ‘$index’, type: ‘$type’$stExtra}";
  57.  
  58.                         $type = ;
  59.                         $stExtra = ;
  60.                         $cmExtra = ;
  61.  
  62.                 }
  63.  
  64.                 $cm .= implode(‘, ‘, $cmArr)."\n\n];\n\n";
  65.                 $st .= implode(‘, ‘, $stArr)."\n\n];";
  66.  
  67.                 $cf = Zend_Registry::get(‘config’);
  68.  
  69.                 $fp = fopen($cf->path->file.‘pub/js/ext-cache/’.$this->_name.‘_gs.js’, ‘a’); // write where ever you wish
  70.  
  71.                 fwrite($fp, $cm.$st);
  72.  
  73.                 fclose($fp);
  74.  
  75.                 chmod($cf->path->file.‘pub/js/ext-cache/’.$this->_name.‘_gs.js’, 0777);
  76.  
  77.         }
  78.  
  79. }

All of my models extend the reverse_db_table so i have allways the functions. Just use once $model->extWriteGridSettings(); and it will write it do disk.

Now the rowset extend.

  1. _table->getCount($where);
  2.  
  3.                 $count = 0;
  4.                 foreach($this->_data as $key => $value) {
  5.                         $arr[$this->_table->info(‘name’)][$count] = $value;
  6.                         $count++;
  7.                 }
  8.  
  9.                 if($count == 0) {
  10.                         $arr[$this->_table->info(‘name’)];
  11.                 }
  12.  
  13.                 return Zend_Json::encode($arr);
  14.  
  15.         }
  16.  
  17. }

Now some usage examples.

  1. public function xmlListAction()
  2. {
  3.         $this->_autoRender = false; // my internal funciton to stop smarty from rendering
  4.         $xmlModel = new xmls(); // the model
  5.         $rs = $xmlModel->fetchAll();
  6.         echo $rs->toExtJson(); // the record set
  7. }

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 :-) ).

Leave a Reply

Icons by N.Design Studio. Designed By Ben Swift. Powered by WordPress and Free WordPress Themes
kill