“Imagination is everything. It is the preview of life's coming attractions”

- Albert Einstein

  • Simple Ext Js 4.x Application Tutorial Part 1


    Simple Ext Js 4.x Application Tutorial Part 1

    This is the first article in the series that covers development of a simple ExtJs based application. Many hate this technology, but still many also use it - so why not give it a try? Basics and some nasty tips’n’tricks will be covered in these tutorials. A word of warning - this one will be a bit robust but with every detail explained.

    At the beginning it’s obviously a common sense practice to determine our goal. We’ll be aiming to develop a small store’s items management application that will allow to view, update, remove and add both items from the database (during the first part replaced by JSON files).

    Part 1 of the tutorial will concern basic application and GUI deployment with JSON data display, each explained step by step. Let’s us start our journey then:

    1. Download Ext JS from Sencha’s website, extract it’s content to your project folder and rename obtained directory to ext-4
    2. Ext JS 4 delivers it’s users a nasty piece of MVC structure which makes it more readable than it was in version 3. Example directory structure used in this tutorial is shown in the image below. Ext Js directory structure

      A bit of explanation concerning folders is required here:

      • app - contains whole Ext JS MVC structure - folders are self-explanatory. If not - check my tutorial about secure mvc website structure,
      • data - storage folder for JSON files or data providers like some small PHP scripts,
      • ext-4 - all Ext JS library files should be in this folder (eg. all CSS and JavaScript files that belong to the package).
    3. Time to create index.html in the root folder of our project and fill it with following content:
      <html>
          <head>
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
              <title id="page-title">Application</title>
              <link rel="stylesheet" type="text/css" href="ext-4/resources/css/ext-all.css">
              <!-- GC -->
              <!-- <x-compile> -->
              <!-- <x-bootstrap> -->
              <script type="text/javascript" src="ext-4/ext-dev.js"></script>
              <!-- </x-bootstrap> -->
              <script type="text/javascript" src="app.js"></script>
              <!-- </x-compile> -->
          </head>
          <body>
          </body>
      </html>
      

      This is a standard index.html template for basic Ext JS applications. Page title is optional here and can be adjusted any way you want it.

    4. Instead of creating the main application initializing script - app.js - let’s first focus on our model. Create a file Item.js in app/model directory with following content:
      Ext.define('Application.model.Item', {
          extend: 'Ext.data.Model',
          fields: ['item_id', 'name', 'description']
      });
      

      Ext.define is used to define a class or override already existing one (extend would be then replaced by override). First attribute of this method - ’Application.model.Item’ - contains: name of the application, Application, that will later be used in app.js file; object type name model; and it’s name - Item (should be the same as the file in which it’s located). It basically forms a namespace for object while also defining it’s name. The rest goes as follows: extend and it’s value defines this object as a certain type, in this case it’s Model class; fields are just an array of fields that are assigned to each single instance of this model.

    5. Since model represents single item, we’ll need to create something that will act as a repository, proxy or peer. It must allow us to read and write models from the data source. In Ext Js such classes are called Store. Let’s create an Items.js file in app/store directory with following code:
      Ext.define('Application.store.Items', {
          extend: 'Ext.data.TreeStore',
          model: 'Application.model.Item',
          autoLoad: true,
          // Define the root of the json file
          root: {
              // Root should be expanded on
              // the application start
              expanded: true
          },
          proxy: {
              // Defined this proxy type
              type: 'ajax',
              // Data source
              url: 'data/items.json',
              // Reader should be configured for 
              // json parsing
              reader: {
                  type: 'json'
              }
          }
      });
      

      This store object extends Ext.data.TreeStore, which is suitable for tree structured data.

    6. Download this JSON file and put it in data folder
    7. Next are views. Views represent certain components or their combinations that are delivered to the user. Create a folder item in app/view directory. In this folder let’s create two files: List.js and Show.js, which will represent two components displayed in the main layout: items list and item details box. List.js contents go as follows:
      Ext.define('Application.view.item.List', {
          extend: 'Ext.tree.Panel',
          // Shorthand name for this object
          alias : 'widget.itemList',
          // Item id - used by Ext.getCmp() method
          title : 'Items',
          // Content provider to this component. Data
          // will be fetched and displayed on startup
          store: 'Items',
          // Disable display of that nasty blank spot
          rootVisible: false,
          // Override default displayed property name - change it from "text" to "name"
          displayField: 'name',
          minWidth: 150
          // IMPORTANT:
          // Trees with defined stores and no additional items do 
          // not require any "layout" parameter here
      });
      

      For Show.js code looks like this:

      Ext.define('Application.view.item.Show', {
          extend: 'Ext.panel.Panel',
          // Shorthand name for this object
          alias : 'widget.itemShow',
          title : 'Item data',
          // Layout configuration
          layout: {
              // Fully stretch this panel to
              // it's container size
              type: 'fit'
          },
          items: [{
              xtype: 'component',
              // Item id - used by Ext.getCmp() method for instance
              // selection
              id : 'item-description',
              // Html inside this component
              html: 'Please select an item on the left',
              // Since adding parameter "padding" to this item 
              // doesn't work - we'll add some direct styles
              style: {
                  padding:'10px'
              }
          }]
      });
      
    8. Having view components defined let’s wrap them all together in Viewport class. Viewport should be treated as a main level component that provides core view configuration and combines all view components. Create a file Viewport.js in app/view directory and fill it with below code:
      Ext.define('Application.view.Viewport', {
          extend: 'Ext.container.Viewport',
          // Layout configuration
          layout: {
              // Items inside will be aligned in a horizotal line
              type: 'hbox',
              // Stretch elements to fit the page size
              align: 'stretch'
          },
          // Enable scrolling of this container once
          // parent element (browser in this case) has
          // been resized below minimal values
          autoScroll: true,
          minWidth: 960,
          // Items array - contains all views attached to the viewport, eg. categories list
          items :  [
              {
                  xtype: 'itemList',
                  flex: 1
      
              },
              {
                  xtype: 'itemShow',
                  flex: 5
              }
          ]
      });
      
    9. Almost there. We’ve got the model, data proxy and views defined. We’ll need something that’ll wrap all this stuff together and process all user input the way we want. And that’s where the controller comes in. In this part of the tutorial our goal is to allow user to select an item from the list component to display it’s description in the item details box (itemShow component). Create ItemController.js file in app/controller directory and insert this code:
      Ext.define('Application.controller.ItemController', {
          // Extend basic controller object
          extend: 'Ext.app.Controller',
          // Attach store classes to this controller
          stores: ['Items'],
          // Attach model classes to this controller
          models: ['Item'],
          // ..and last but not least - the view classes
          views: ['item.List', 'item.Show'],
          // Refs parameter defines references to certain
          // instances of components pointed by selector
          refs: [
              {
                  // Ref determines the name of the automagic
                  // this.get[ref-goes-here] method that returns
                  // instance of certain component
                  ref : 'itemShowDesc',
                  // Select #item-description component in
                  // item.Show view
                  selector: 'itemShow > #item-description'
              }
          ],
          // when including the controllers in your application, 
          // the framework will automatically load the controller 
          // and call the init method on it
          init: function() {
              this.control({
                  'itemList' : {
                      // Action to be performed on select
                      select: this.onItemSelect
                  }
              });
          },
          onItemSelect: function (selModel, selection) {
              // Executed only when selection is a leaf
              (selection.data.leaf) ? this.getItemShowDesc().update(selection.raw.description) : null;
          }
      });
      
    10. One little finishing touch - Ext Js will require a script that will actually launch our application. For that create app.js file in the root of your project with following content:
      Ext.application({
          name: 'Application',
          // Automatically create an instance of AM.view.Viewport
          // on application launch
          autoCreateViewport: true,
          // Attach controllers
          controllers: ['ItemController']
      });
      

    Phew, now that was quite a bit of text to read, wasn’t it? You can launch your application and see how it engulfs you with eternal glory and endless might! Also, stay vigilant for the next part of the tutorial, where we’ll add add/edit/removal interface for each item and make a basic server-side data provider. Cheers!

    Back