Dynamic GridPanel for ExtJs 4
Recently, I was trying to update our internal system from ExtJs 3 to version 4. Well, I think many V3 plugins are needed to be updated. So I was a bit busy on that... Anyway, I am going to share a bit of code which is the dynamic grid for ExtJs 4. As the sample from Erhan Abay is for ExtJs 3, so I made a few changes for ExtJs 4.


/**
* Ext.ux.grid.DynamicGridPanel
*/
Ext.define('Ext.ux.grid.DynamicGridPanel', {
    extend: 'Ext.grid.GridPanel',
    alias: 'widget.dynamicgrid',
    /**
    * initialising the components
    */
    initComponent: function(){
        /**
        * set the config we want
        */
        var config = {
            columns:[],
            rowNumberer: false
        };
        
        // appy to this config
        Ext.apply(this, config);
        // apply to the initialConfig
        Ext.apply(this.initialConfig, config);
        // call the arguments
        this.callParent(arguments);
    },
    /**
    * When the store is loading then reconfigure the column model of the grid
    */
    storeLoad: function()
    {
        /**
        * JSON data returned from server has the column definitions
        */
        if(typeof(this.store.proxy.reader.jsonData.columns) === 'object') {
            var columns = [];
            /**
            * adding RowNumberer as we need to add them 
            * before other columns to display first
            */
            if(this.rowNumberer) { columns.push(Ext.create('Ext.grid.RowNumberer')); }
            /**
            * assign new columns from the json data columns
            */
            Ext.each(this.store.proxy.reader.jsonData.columns, function(column){
                columns.push(column);
            });
            /**
            *  reconfigure the column model of the grid
            */
            this.reconfigure(this.store, columns);
        }
    },
    /**
    * assign the event to itself when the object is initialising
    */
    onRender: function(ct, position){
            /**
            *  well, old fashion way, but works well.
            */
            Ext.ux.grid.DynamicGridPanel.superclass.onRender.call(this, ct, position);
            /**
            * hook the store load event to our function
            */
            this.store.on('load', this.storeLoad, this);
    }
});

Client Side Example: (Tested on ExtJs 4.0.7 and 4.1.1)
// Start loading the page        
Ext.onReady(function(){
    // we need to define the model but the field values will be parsed
    // automatically since we provided fields in the metaData from server
   Ext.define('dynamicModel', {
     extend: 'Ext.data.Model',
     //set the proxy
     proxy: {
       type: 'rest',
       url: 'data.php' // the sample server address
     }
   });
   // create a data store
   var myStore = Ext.create('Ext.data.Store', {
         model:'dynamicModel',
         autoLoad:true,
   });    
   // create dynamic grid
   var myGrid = {
       title:'Dynamic Grid',
       xtype:'dynamicgrid',
       forceFit:true,
       region:'center',
       store:myStore,
       dockedItems: [{
         xtype: 'pagingtoolbar',
         store: myStore,
         dock: 'bottom',
         displayInfo: true
       }]              
   };   
    // finally, build the main layout once all the pieces are ready.
    Ext.create('Ext.container.Viewport', {
        layout:'border',
        items:[myGrid]
    });
});

Server Side Example: (data.php)
    
    $total = 100;
    // you can pre-define the required property parameters
    $output["metaData"]["idProperty"]="id";
    $output["metaData"]["totalProperty"]="total";
    $output["metaData"]["successProperty"]="success";
    $output["metaData"]["root"]="data";
    // you can parse field values via your database schema
    $output["metaData"]["fields"][]=array("name"=>"id","type"=>"int");
    $output["metaData"]["fields"][]=array("name"=>"name","type"=>"string");
    $output["metaData"]["fields"][]=array("name"=>"firstName","type"=>"string");
    $output["metaData"]["fields"][]=array("name"=>"lastName","type"=>"string");
    // you can parse column values via your database schema
    $output["columns"][]=array("dataIndex"=>"id","header"=>"ID", "width"=>10);
    $output["columns"][]=array("dataIndex"=>"name","header"=>"User Name","width"=>20);
    $output["columns"][]=array("dataIndex"=>"firstName","header"=>"First Name");
    $output["columns"][]=array("dataIndex"=>"lastName","header"=>"Last Name");
    // the misc properties
    $output["total"]=$total;
    $output["success"]=true;
    $output["message"]="success";
    // parse pages     
    $start = $_GET['start'] + 1;
    $max = $_GET['start'] + $_GET['limit'];
    // make sample data
    for($i = $start; $i <= $max; $i++ ){
     $output["data"][]= array(
                    "id"=>$i,
                    "name"=>"UserName-". $i,
                    "firstName"=>"My First Name No. ". $i,
                    "lastName"=>"My Last Name No. ". $i);
    }    
    // output the value
    echo json_encode($output);