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:
- Download Ext JS from Sencha’s website, extract it’s content to your project folder and rename obtained directory to ext-4
- 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.
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).
-
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.
-
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.
-
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.
- Download this JSON file and put it in data folder
-
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' } }] });
-
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 } ] });
-
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; } });
-
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!