Dynamic GridPanel for ExtJs 4

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

55 comments :

  1. Hi Elvis, great post! I was toying around with this trying to get it to work, by re-using Erhans Ext 3 code / JSON. I can get the panel to render by its not rendering columns or rows.

    I was hoping you could tell me what format of JSON or store/proxy are you using? And how do you config the dynamic grid?

    Thanks!

    ReplyDelete
  2. Ext.create('Ext.data.Store', {
    storeId:'urlStore',
    proxy: {
    type: 'rest',
    url : '../js/dynamic_grid.json',
    reader: {
    type: 'json'
    }
    }
    });


    Ext.create('Ext.ux.grid.DynamicGridPanel', {
    id: 'my-grid',
    title: 'url grid',
    store: Ext.data.StoreManager.lookup('urlStore'),
    rowNumberer: true,
    selModel: Ext.create('Ext.selection.CheckboxModel'),
    height: 200,
    width: 400,
    renderTo: Ext.getBody()
    });


    //(That's what I'm trying at the moment)

    ReplyDelete
  3. Hi, Neil,
    Did you put the "metaData" in your JSON? Ext4 omits the documentation on the metaData of the proxy. That is quite a tricky part...

    Have a look at the following JSON sample... Hope it will help you...

    {"metaData":{"idProperty":"id","totalProperty":"total","successProperty":"success","root":"data","fields":[{"name":"ID","type":"int","allowBlank":false,"defaultValue":"0"},{"name":"USER","type":"string","allowBlank":false,"defaultValue":""},{"name":"HOST","type":"string","allowBlank":false,"defaultValue":""},{"name":"DB","type":"string","allowBlank":true,"defaultValue":null},{"name":"COMMAND","type":"string","allowBlank":false,"defaultValue":""},{"name":"TIME","type":"int","allowBlank":false,"defaultValue":"0"},{"name":"STATE","type":"string","allowBlank":true,"defaultValue":null},{"name":"INFO","type":"string","allowBlank":true,"defaultValue":null}]},"success":true,"total":1,"message":"Loaded data","data":[{"ID":"12177","USER":"BCD","HOST":"::1:10649","DB":"information_schema","COMMAND":"Query","TIME":"0","STATE":"executing","INFO":"SELECT * FROM `PROCESSLIST` LIMIT 0,50"}],"columns":[{"header":"ID","dataIndex":"ID","sortable":true},{"header":"USER","dataIndex":"USER","sortable":true},{"header":"HOST","dataIndex":"HOST","sortable":true},{"header":"DB","dataIndex":"DB","sortable":true},{"header":"COMMAND","dataIndex":"COMMAND","sortable":true},{"header":"TIME","dataIndex":"TIME","sortable":true},{"header":"STATE","dataIndex":"STATE","sortable":true},{"header":"INFO","dataIndex":"INFO","sortable":true}]}

    ReplyDelete
  4. Hi Elvis,

    I already had the JSON from Erhan's (http://erhanabay.com/2009/01/29/dynamic-grid-panel-for-ext-js/) then I realised on comparing it to yours that there was only the metadata in his example and no actual data to render in the cells.

    So now I'm using your JSON, I'm just not convinced I'm doing the config correctly (see above for my config of DynamicGridPanel and DynamicGridPanel)

    In Erhan's example; storeUrl: 'server/url/address/', is used, in the config of DynamicGridPanel, this didn't work for me so I tried configuring a store with my url. I will keep tinkering with it.

    I couldn't find information on configuring proxies with metaData... yet...

    ReplyDelete
  5. Hi, Neil,
    If you use the metaData on server response, you will find the json reader applies the metaData but not the data Model. Also, I think you should use 'ajax' as your proxy type instead of 'rest' if you don't use 'rest' method on your server side.

    ReplyDelete
  6. in ExtJS 4 is - extend: 'Ext.grid.Panel'
    not 'Ext.grid.GridPanel'!

    ReplyDelete
  7. Hi, serju, I think both alias wrok.

    ReplyDelete
  8. Thanks Elvis, I've not had a successful render yet.
    I switched to 'Ajax' instead of rest. One thing I noticed was the store was coming in empty, so I thought I try call to load the store and the loading spinner hangs and it comes up with the error; reader.read is not a function
    [Break On This Error] result = reader.read(me.extractResponseData(response));

    Please could you post your code where you are calling the DynamicGridPanel from?

    ReplyDelete
  9. Hi, Neil,
    Try below sample codes and I think it should work as I didn't test it.

    ==================================================
    Ext.define('MyModel', {
    extend: 'Ext.data.Model',
    proxy: {
    type: 'ajax',
    url : '../js/dynamic_grid.json'
    }
    });

    var MyStore = Ext.create('Ext.data.Store', {
    model: 'MyModel'
    });

    Ext.create('Ext.ux.grid.DynamicGridPanel', {
    id: 'my-grid',
    title: 'url grid',
    store: MyStore,
    rowNumberer: true,
    selModel: Ext.create('Ext.selection.CheckboxModel'),
    height: 200,
    width: 400,
    renderTo: Ext.getBody()
    });

    //uses the Proxy we set up on Model to load the Store data
    MyStore.load();
    ===================================================

    ReplyDelete
  10. Thanks Evlis, I can see now that what I was doing wrong and that I hadn't grasped what you were saying earlier on. It totally works now having the URL in the model! I had assumed that because it was dynamic, it wouldn't need a model, but this works so I can see this coming in very useful indeed! :)

    ReplyDelete
  11. No worries, mate. Glad that I could help you out... I had troubles on migrating extjs 3 to 4. It took me a long time to go though the source codes to migrate.

    Cheers,
    Elvis

    ReplyDelete
  12. Thanks Elvis. It tried your code. it is working properly.

    Thanks to all of you who posted.

    ReplyDelete
  13. Helo Elvis,

    What about the XML instead of JSON, I want to parse XML instead of JSON for columns and rows.

    Durrab

    ReplyDelete
    Replies
    1. Hi, Durrab,
      I believe if you use xml store (http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Xml), it should do the same job.

      Regards,
      Elvis

      Delete
  14. Hi Elvis,
    thanks for your work.
    I have a problem with "idProperty". When I edit the record and then I try to sync the store, data sent to server are wrong. Sended data are [{"name":"Ondra","id":null}] but should be [{"name":"Ondra","userId":1}] (default ID column si used). Looks like idProperty is not set properly.

    ReplyDelete
  15. Set idProperty on your model config.

    example:
    Ext.define('MyApp.model.TableAModel', {
    extend: 'Ext.data.Model',
    idProperty: 'ID',

    fields : [
    {name: 'ID'},
    {name: 'FAMILYNAME'},
    {name: 'TABLENAME'},
    ...

    ReplyDelete
  16. Hi Elvis,

    Can you please add paging to this code? I tried doing, but in vain, I have been working for quite some time in the following,

    http://www.sencha.com/forum/showthread.php?242594-Dynamic-grid-with-dynamic-model

    I tried adding totalProperty, but couldn't do it. Better if you could help me with my example.

    Thanks in advance!

    ReplyDelete
    Replies
    1. Hi,
      If you are using paging tool bar, the datastore only help you to calculate the total pages but not limit the displaying rows if you feed it all of your data.
      For example if I do a query "http://my_url/my_mvc?_dc=1357361116763&tbl=my_table&page=1&start=0&limit=50"
      then my ajax json result would like below:

      =====================================================
      columns: [{header:GRANTEE, dataIndex:GRANTEE, sortable:true},…]
      data: [{…},…] <-- only first 50 rows
      message: "Loaded data"
      metaData: {idProperty:id, totalProperty:total, successProperty:success, root:data,…}
      success: true
      total: 126 <-- from server
      =====================================================
      From above result, we want to show 50 rows per page out of 126 records, so the datastore calculates 3 pages for you.
      If you want to show second page, the data store will send this query "http://my_url/my_mvc?_dc=1357361116763&tbl=my_table&page=2&start=50&limit=50" to server, and then you get the second 50 rows.

      You need to limit the rows on server side but datastore helps you to feed the queries. Anyway, server side code is what you need to look at.
      Just have a look at the url query when you debug your code.

      Cheers,
      Elvis

      Delete
    2. This comment has been removed by the author.

      Delete
  17. Hi Elvis,

    Thanks for the reply, I am aware of server side coding, if I do like you mentioned it does form url exactly like you said. You gone through the link I mentioned in first post? They just pass JSON like,

    ============================================
    [{
    "userId": 123,
    "name": "Ed Spencer",
    "email": "ed@sencha.com"
    }]
    ============================================

    I did try with root like,

    ============================================
    {
    "count": 1,
    "ok": true,
    "msg": "Users found",
    "users": [{
    "userId": 123,
    "name": "Ed Spencer",
    "email": "ed@sencha.com"
    },{
    "userId": 123,
    "name": "Ed Spencer",
    "email": "ed@sencha.com"
    }],
    "metaData": {
    "root": "users",
    "idProperty": 'userId',
    "totalProperty": 'count',
    "successProperty": 'ok',
    "messageProperty": 'msg'
    }
    }
    ============================================

    But I couldn't pass totalProperty to DynamicGrid.js, could you please go through that code and help me with coding?

    Thanks :).

    ReplyDelete
    Replies
    1. Can you show me simple version of your code and data? Also, from the data above you have provided, the values of userId are same, so it will only show one in the grid since the idProperty is set to "userId".
      Did you assign DataStore to your PagingToolbar?

      Delete
    2. This comment has been removed by the author.

      Delete
  18. I am adding totalProperty in DynamicGrid.js, but doesn't work,

    =======================================================================
    /*
    * Dynamic grid, allow to display data setting only URL.
    * Columns and model will be created dynamically.
    */
    Ext.define('Ext.ux.grid.DynamicGrid', {
    extend: 'Ext.grid.Panel',
    alias: 'widget.dynamicGrid',
    alternateClassName: 'Ext.grid.DynamicGrid',
    requires: ['Ext.ux.data.reader.DynamicReader'],
    // URL used for request to the server. Required
    url: '',
    root: 'users',
    successProperty: 'success',
    messageProperty: 'message',
    totalProperty: 'total',
    pageSize: 10,
    isAutoLoad: false,
    isRemoteSort: false,
    isPagination: true,
    initComponent: function () {
    var me = this;
    if (me.url == '') {
    Ext.Error.raise('url parameter is empty! You have to set proper url to get data form server.');
    } else {
    var store = Ext.create('Ext.data.Store', {
    // Fields have to be set as empty array. Without this Ext will not create dynamic model.
    fields: [],
    // After loading data grid have to reconfigure columns with dynamic created columns
    // in Ext.ux.data.reader.DynamicReader
    listeners: {
    metachange: function (store, meta) {
    me.reconfigure(store, meta.columns);
    }
    },
    pageSize: me.pageSize,
    autoLoad: me.isAutoLoad,
    remoteSort: me.isRemoteSort,
    proxy: {
    type: 'rest',
    format: '',
    url: me.url,
    reader: {
    type: 'dynamicReader', hiddenColumns: me.hiddenColumns, root: me.root, successProperty: me.successProperty, messageProperty: me.messageProperty,
    totalProperty: 'total'
    },

    listeners: {
    exception: function (httpProxy, response, operation, eOpts) {
    Ext.MessageBox.show({
    title: 'Error Message',
    msg: response.responseText,
    buttons: Ext.MessageBox.OK,
    width: 400,
    auoScroll: true,
    closable: false,
    icon: Ext.MessageBox.ERROR
    });
    }
    },
    simpleSortMode: true
    }
    });
    console.log(me.root);
    console.log(me.totalProperty);
    Ext.applyIf(me, {
    columns: [],
    forceFit: true,
    store: store
    });

    if (me.isPagination) {
    Ext.applyIf(me, {
    tbar: Ext.create('Ext.PagingToolbar', {
    pageSize: me.pageSize,
    store: store,
    prependButtons: false,
    displayInfo: true,
    beforePageText: 'Page',
    displayMsg: 'Displaying {0} to {1} of {2} records'
    })
    });
    }
    }
    me.callParent(arguments);
    }
    });
    ==============================================================================

    ReplyDelete
    Replies
    1. DynamicReader.js to get data with root,

      ===================================================================
      /**
      * @class Ext.ux.data.DynamicReader
      * @extends Ext.data.reader.Json
      * Dynamic reader, allow to get working grid with auto generated columns and without setting a model in store
      */
      /**
      * floatOrString data type provide proper sorting in grid for string and float
      * if you don't now what data type of that two whould be in column
      */
      Ext.apply(Ext.data.Types, {
      FLOATORSTRING: {
      convert: function (v, n) {
      v = Ext.isNumeric(v) ? Number(v) : v;
      return v;
      },
      sortType: function (v) {
      v = Ext.isNumeric(v) ? Number(v) : v;
      return v;
      },
      type: 'floatOrString'
      }
      });

      Ext.define('Ext.ux.data.reader.DynamicReader', {
      extend: 'Ext.data.reader.Json',
      alias: 'reader.dynamicReader',
      alternateClassName: 'Ext.data.reader.DynamicReader',

      hiddenColumns: undefined,
      root: '',

      readRecords: function (records) {
      var data = records['users'];
      console.log(JSON.stringify(data));
      if (data.length > 0) {
      var item = data[0],
      fields = new Array(),
      columns = new Array(),
      total = new Array(),
      p = null,
      isHiddenColumns = this.hiddenColumns != undefined && this.hiddenColumns.length > 0;
      for (p in item) {
      if (p && p != undefined) {
      // floatOrString type is only an option
      // You can make your own data type for more complex situations
      // or set it just to 'string'
      fields.push({name: p, type: 'floatOrString'});
      if (isHiddenColumns) {
      if (Ext.Array.contains(this.hiddenColumns, p)) {
      columns.push({text: p, dataIndex: p, hidden: true, hideable: false});
      } else {
      columns.push({text: p, dataIndex: p, hidden: false});
      }
      } else {
      columns.push({text: p, dataIndex: p});
      }
      }
      }
      total.push({totalProperty: '10'});
      data.metaData = { fields: fields, columns: columns, total: '10' };
      }
      console.log(JSON.stringify(this.callParent([data])));
      return this.callParent([data]);
      }
      });
      ===================================================================

      Delete
    2. I just need to add url like,

      ================================================================
      /**
      * The main application viewport, which displays the whole application
      * @extends Ext.Viewport
      */
      Ext.define('Ext4Example.view.Viewport', {
      extend: 'Ext.Viewport',
      layout: 'fit',

      requires: [
      'Ext.ux.grid.DynamicGrid'
      ],

      initComponent: function() {
      console.log('Viewport initComponent!');

      var me = this;

      Ext.apply(me, {
      items: [
      {
      xtype: 'dynamicGrid',
      url: 'data/data.php',
      root: 'users',
      //pageParam: false,
      //startParam: false,
      //limitParam : false,
      isPagination: true,
      pageSize: 10,
      isRemoteSort: true,
      isAutoLoad: true,
      noCache: false,
      actionMethods: {
      read: 'GET'
      },
      extraParams: {
      action: 'load'
      },
      headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
      },
      hiddenColumns: ['Data'],
      rowLines: false,
      columnLines: false,
      margin: 5,
      enableColumnHide: true,
      selType: 'rowmodel',
      viewConfig: {
      stripeRows: true,
      forceFit: true,
      emptyText: "No data found.",
      deferEmptyText: false
      }
      }
      ]
      });

      me.callParent(arguments);
      }
      });
      ================================================================

      Delete
    3. This comment has been removed by the author.

      Delete
    4. I think you should change (totalProperty: 'total') to (totalProperty: me.totalProperty) in the "initComponent" function since your data tells you totalProperty is "count" instead of "total".

      Delete
    5. I tried that too, didn't work.

      Delete
    6. Those count and total are just examples, that was edited, I tried with exact totalProperty, didn't do. May be I should do something in the listener which is reconfiguring grid for paging also?

      Delete
    7. Hi,
      Can you try few changes?
      1. Change your reader type from 'dynamicReader' to 'json'
      2. Remove all *Property since the metaData should provide these parameters
      3. Remove DataStore's listener 'metachange' to 'load' and use the one
      I have in the original post.

      What version of ExtJs are you using? Try 4.0.7 or 4.1.1a because both versions work for me with my recommended changes. I found out some issues on your DynamicDataReader class.

      Regards,
      Elvis

      Delete
    8. Hi Elvis,

      1. If I change type to 'json', it takes totalProperty showing all pages and making url from server side, but doesn't form data in the grid since metaData is actually coming from DynamicReader.js which we are stopping with 'json' type. So metachange will not have dynamic model that will be created to reconfigure.
      2. Tried removing all properties, it does work with just 'dynamicReader' type and root mentioned in it.
      3. If I change 'metachange' to 'load' it will not have metaData, so obviously won't form grid.

      I am using 4.2.0 now, initially started with 4.1.1, shifted to this for better performance.

      May be I can try with your plugin, I should just call in my VIEW right? Seems like from your comments, I have to create a model also. I have to try paging in it. A working example in github or somewhere will be of great help :).

      BTW thanks for your replies.

      Delete
    9. Hi,
      I have added the client and server side example on the original post. I hope this can help you out.

      Regards,
      Elvis

      Delete
    10. Hi Elvis, I tried you coding, it works good, my PHP input will just have a query which forms JSON response, but your example returns with fields and columns, so now I am trying to modify server code. And also I am working with MVC type, trying for that, I will let you know if everything is successful.

      Thanks again for your code :).

      Delete
    11. Hi Elvis,

      PHP was simple, I was able to do and it works like a charm. But now as I am trying with MVC type, having some issues, I will show simple code, can you please help me correct it?

      VIEW
      ======================================================================
      Ext.define('MyApp.view.MyPanel', {
      extend: 'Ext.panel.Panel',

      requires: ['Ext.ux.grid.DynamicGridPanel'],

      height: 346,
      width: 716,
      layout: {
      type: 'absolute'
      },
      title: 'My Panel',

      initComponent: function() {
      var me = this;

      Ext.applyIf(me, {
      items: [
      {
      xtype: 'gridpanel',
      x: 20,
      y: 20,
      autoRender: true,
      xtype:'dynamicgrid',
      height: 140,
      width: 410,
      title: 'My Grid Panel',
      store: 'MyJsonStore'
      },
      {
      xtype: 'pagingtoolbar',
      x: 20,
      y: 160,
      height: 30,
      width: 410,
      displayInfo: true,
      store: 'MyJsonStore'
      }
      ]
      });

      me.callParent(arguments);
      }

      });
      ======================================================================

      MODEL
      ======================================================================
      Ext.define('MyApp.model.MyModel', {
      extend: 'Ext.data.Model',

      proxy: {
      type: 'rest',
      url: 'dynamic.php'
      }
      });
      ======================================================================

      STORE
      ======================================================================
      Ext.define('MyApp.store.MyJsonStore', {
      extend: 'Ext.data.Store',

      requires: [
      'MyApp.model.MyModel'
      ],

      constructor: function(cfg) {
      var me = this;
      cfg = cfg || {};
      me.callParent([Ext.apply({
      autoLoad: true,
      storeId: 'MyJsonStore',
      model: 'MyApp.model.MyModel',
      pageSize: 50
      }, cfg)]);
      }
      });
      ======================================================================

      Delete
    12. Hi,

      It says "name is undefined" when I add xtype: 'dynamicgrid', what is going wrong? Sorry to bother you again, can you please help me out?

      Delete
    13. I found the mistake, have to change xtype to dynamicGridPanel and it works great. Thanks very much for all your help, your code helped me alot.

      Delete
  19. My server side coding,

    ====================================================================
    $totRec, 'root' => 'users');
    echo $sql = "SELECT * FROM users LIMIT " . $sStart . ", " . $numOfRowsUserChose;
    $rs = mysql_query($sql);
    $arrData = array();
    if (mysql_num_rows($rs)){
    while ($obj = mysql_fetch_object($rs)){
    $arrData[] = $obj;
    }
    }
    $arrayData['users'] = $arrData;
    echo json_encode($arrayData);
    ?>
    ==================================================================

    ReplyDelete
  20. The same can be achieved without using dynamic grid concept....

    * Define an empty store with empty fields.
    * Define a empty grid with the defined store.
    * Generate columns & data.
    * Make an ajax call for the function.
    ex : test.php?cmd=generateData
    * assign the columns to the grid.
    ex : grid.reconfigure(store, result.columns);
    * load the data returned as result from ajax
    ex : grid.store.loadData(result.data);

    NOTE : result is response from the PHP function.

    Regards,
    Anoop Pete
    anoop.pete@gmail.com

    ReplyDelete
    Replies
    1. Hi, Anoop,
      Thank for your recommendation. The dynamic grid concept is same as your suggestion. I just wrap these loose calls into a class as I use dynamic grid quite often. I thought it would be easier for me.

      Thanks again,
      Elvis

      Delete
  21. myGrid .columns returns an empty array. I want to get all the columns non-hidden, and send them to the server

    ReplyDelete
    Replies
    1. Hi, Ken,
      Could you please give more information about what you want to achieve?

      Elvis

      Delete
  22. I want to grab the state of the columns and use them somewhere else... i.e .. if have like 10 columns in the grid, the user can hide/un-hide any 3 of them.. now i want to grab now all this columns with their current states and use that information somewhere else in my application..

    ReplyDelete
    Replies
    1. Hi, Ken,
      My suggestion would be looking at this link

      http://docs.sencha.com/extjs/4.1.1/#!/api/Ext.grid.header.Container-method-getGridColumns

      to get all columns of this grid.

      I assume the returned data does not contain any information about the hidden status of each column. So you can use below method to get visible columns of current grid.

      http://docs.sencha.com/extjs/4.1.1/#!/api/Ext.grid.header.Container-method-getVisibleGridColumns

      You can cross reference them and cache the result in anywhere of your application for future use.

      Hope this helps,
      Elvis

      Delete
    2. console.log(grid.getView().getHeaderCt().getGridColumns()); this is giving me an empty array too.

      Delete
  23. Hi,
    I am getting error as
    Ext.ux.grid.DynamicGridPanel is undefined, i do not see ux folder in extjs4.2 , do ineed to put extra js in my 4.2 folder?

    ReplyDelete
    Replies
    1. At beginning of your page, between head tags, you should have the following configuration in your Javascript section. Before Ext.onReady()

      Ext.Loader.setConfig({enabled: true});
      Ext.Loader.setPath('Ext.ux', '../Scripts/Library/Ext/ux');
      Ext.require(['Ext.ux.grid.DynamicGridPanel', '*']);

      Your "Ext.ux.grid.DynamicGridPanel" should have the file name "DynamicGridPanel.js" under "../Script/Library/Ext/ux/grid/" folder. So the whole path of your file would be "../Script/Library/Ext/ux/grid/DynamicGridPanel.js"

      Delete
  24. Is it my app or what, Row hover highlighting is not working with this example

    ReplyDelete
    Replies
    1. Hi, Ken,

      Can you show me your config code?

      Cheers,

      Elvis

      Delete
  25. Hi Ken,
    Thanks for your reply.I am able to display the grid properly.Thsi post is awesome.
    I am trying to build dynsmic grid that does CRUDE operation. SO far i am not abe to display the Textboxes in dynamic grid .Below is my json

    {
    "gridName": "MugdhaGrid",
    "columns": [
    {
    "editor": {
    "xtype": "textfield"
    },
    "hidden": false,
    "sortable": true,
    "width": 100,
    "dataIndex": "First_Name",
    "header": "First_Name"
    },
    {
    "editor": {
    "xtype": "textfield"
    },
    "hidden": false,
    "sortable": true,
    "width": 100,
    "dataIndex": "id",
    "header": "id"
    },
    {
    "editor": {
    "xtype": "textfield"
    },
    "hidden": false,
    "sortable": true,
    "width": 100,
    "dataIndex": "Salary",
    "header": "Salary"
    },
    {
    "editor": {
    "xtype": "textfield"
    },
    "hidden": false,
    "sortable": true,
    "width": 100,
    "dataIndex": "Last_Name",
    "header": "Last_Name"
    }
    ],
    "gridData": [
    {
    "id": "1",
    "Last_Name": "Churi",
    "First_Name": "Sita",
    "Salary": "5000"
    },
    {
    "id": "2",
    "Last_Name": "Smith",
    "First_Name": "Jen",
    "Salary": "6000"
    },
    {
    "id": "3",
    "Last_Name": "Pitt",
    "First_Name": "Brad",
    "Salary": "2000"
    },
    {
    "id": "4",
    "Last_Name": "Cruise",
    "First_Name": "Tom",
    "Salary": "8000"
    }
    ],
    "metaData": {
    "root": "gridData",
    "idProperty": "dynaGridId",
    "fields": [
    {
    "name": "First_Name",
    "type": "string"
    },
    {
    "name": "id",
    "type": "string"
    },
    {
    "name": "Salary",
    "type": "string"
    },
    {
    "name": "Last_Name",
    "type": "string"
    }
    ]
    }
    }

    Can anybody please tell me whats wrong in the code?

    ReplyDelete
  26. Thanks Elvis for your reply . can you please give a hint of how to do CRUDE operations on dynamicgrid. I am not able to display textbox from json

    ReplyDelete
    Replies
    1. Hi, Muglee,

      Have a look at the following link:
      http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.grid.Panel-cfg-plugins

      In you config object, you need to place cellediting plugin

      plugins: [{ptype: 'cellediting', clicksToEdit: 1}],

      Cheers,

      Elvis

      Delete
    2. Hi, Muglee,

      You are very welcome. Does it work for you?

      Elvis

      Delete