Sunday, February 7, 2010

An Implementation of the ExtJs GridPanel

So in my last post I demonstrated how I put together some an ExtJs TabPanel. Now this is not the only way to do this, but it is one way. Now I'm going to take you through how I put together an ExtJs GridPanel.

The html is remarkably simple.

<div id="CategoriesContainer">
    <div class="TabContent"></div>
</div>

Next comes the more complex part of the implementation :)

$(document).ready(function() {

 $.namespace("category", {
  inherited: true,

  InitialiseControl: function() {
   $.fn.category.LoadCategoryGrid();
  },

  LoadCategoryGrid: function() {

   var tabContent = $("#CategoriesContainer").children(".TabContent");

   var proxy = new Ext.data.HttpProxy({
    url: 'Data/Categories.aspx'
   });

   var reader = new Ext.data.JsonReader({
    root: 'Data',
    totalProperty: 'Count',
    idProperty: 'CategoryId',
    fields: [
     { name: 'CategoryId', type: 'int' },
     { name: 'CategoryName', type: 'string', allowBlank: false },
     { name: 'BudgetAmount', type: 'float', allowBlank: false },
     { name: 'IsActive', type: 'boolean' },
     { name: 'Timestamp', type: 'date', dateFormat: 'M$' },
     { name: 'Version', type: 'auto' }
    ]
   });

   var writer = new Ext.data.JsonWriter({
    encode: true,   // <-- don't return encoded JSON -- causes Ext.Ajax#request to send data using 
        // jsonData config rather than HTTP params
    writeAllFields: true
   });

   var store = new Ext.data.Store({
    id: 'dsCategores',
    proxy: proxy,
    reader: reader,
    writer: writer,
    listeners: {
     'update': function(store, record, operation) {
      store.commitChanges();
     },
     'remove': function(store, record, index) {
      store.commitChanges();
     }
    }
   });

   var colModel = new Ext.grid.ColumnModel({
    defaults: {
     sortable: true
    },
    columns: [
     {header: 'Name', dataIndex: 'CategoryName', editor: new Ext.form.TextField({}) },
     { header: 'Budget Amount', dataIndex: 'BudgetAmount', xtype: 'numbercolumn', format: '$0,0.00', align: 'right', editor: new Ext.form.NumberField({}) },
     { header: 'Active', dataIndex: 'IsActive', xtype: 'booleancolumn', trueText: 'Yes', falseText: 'No', align: 'center', editor: new Ext.form.Checkbox({}) }
    ]
   });

   // use RowEditor for editing
   var editor = new Ext.ux.grid.RowEditor({
    saveText: 'Update'
   });

   var grid = new Ext.grid.GridPanel({
    iconCls: 'icon-grid',
    frame: true,
    title: 'Categories',
    loadMask: true,
    autoScroll: true,
    height: 300,
    store: store,
    plugins: [editor],
    colModel: colModel,
    tbar: [{
     text: 'Add',
     iconCls: 'silk-add',
     handler: function(btn, ev) {
      var u = new grid.store.recordType({
       Description: '',
       Amount: '',
       IsActive: true
      });
      editor.stopEditing();
      grid.store.insert(0, u);
      editor.startEditing(0);
     }
    }, '-', '->', '-', {
     text: 'refresh',
     iconCls: 'silk-table-refresh',
     handler: function() {
      grid.store.load();
     }
    }],
    viewConfig: {
     forceFit: true
    }
   });

   grid.render(tabContent[0]);

   store.load();
  }
 });
});

So what's actually going on here?

Firstly,
$(document).ready(function() {
  $.namespace("category", {
    inherited: true,

    InitialiseControl: function() {
      $.fn.category.LoadCategoryGrid();
    },
Here I am using a jquery namespace pluging to create (oddly enough!) a namespace for the javascript for this particular control (or tab). The line inherited: true allows you to interact with function parameters as normal, rather than referring to them as params[0], params[1] etc.

The rest of the javascript is fairly standard ExtJs syntax and extensive definitions can be found at the ExtJs API, but in short I follow these steps when setting up a grid:

  1. Create a proxy object and set the URL it should post to;
  2. Create a reader object. In my case it's a JsonReader and I set the properties that allow the object to interact with the returned Json data;
  3. Create a writer object. This creates default CRUD actions for you;
  4. Create a store object and set up listeners for update and delete calls (mind you I'm not actually deleting anything);
  5. Create a column model for the grid. This maps the fields from the reader to the columns;
  6. Create a RowEditor object. This is a plug-in that gets applied to the grid and can be downloaded from an ExtJs example Grid with RowEditor;
  7. Create the grid;
  8. Get the grid to render to a particular DOM element;
  9. And lastly load the store object;

Next up will be a short post on how to deal with the Ajax requests server side in a C# environment.

Enjoy!

No comments:

Post a Comment