Ext JS - Learning Center

Sandbox:Application Layout for Beginners

From Learn About the Ext JavaScript Library

Jump to: navigation, search
Summary: This tutorial helps you to create your application right way.
Author: Jozef Sakalos
Published: August 25, 2007
Ext Version: 1.1
Languages: en.png English

Contents

Before you start

This tutorial assumes that you have already installed ExtJS - JavaScript Library and that it is installed in directory extjs one directory up from our application directory. If you have installed Ext JS elsewhere you will need to change paths in src attributes of script tags in example files.

What we need?

Besides the ExtJS - JavaScript Library we need two files:

  • applayout.html
  • applayout.js


Let's start with files with minimum content. Here they are together with detailed explanation:

applayout.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <link rel="stylesheet" type="text/css" href="../extjs/resources/css/ext-all.css">
    <script type="text/javascript" src="../extjs/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="../extjs/ext-all-debug.js"></script>
    <script type="text/javascript" src="applayout.js"></script>
    <!-- A Localization Script File comes here -->
    <script type="text/javascript">
        Ext.onReady(myNameSpace.app.init, myNameSpace.app);
    </script>
    <title>Application Layout Tutorial</title>
</head>
<body>
</body>
</html>


First two lines specify document type. The application would run without doctype, however, in this case the browser would probably go into Quirks Mode which wouldn't add to cross-browser compatibility of your application.

We will use HTML 4.01 Transitional for the purpose of this tutorial because this doctype is supported very well by all major browsers. Of course, you can use any other document type if you want or need but keep in mind that you should always specify a doctype.

After the start of html and head comes Content-Type specification. Again, your application can live without it but it should be there.

Then we include Ext styles, adapter and ExtJS itself. There are two versions of ExtJS:

  • ext-all.js - human unreadable, loads faster, for production
  • ext-all-debug.js - human readable, for development

We're going to develop, include debug version then.

Then comes our application applayout.js and, after it, any localization scripts that can override English texts in applayout.js and ExtJS with translated versions before the application is initialized.

Now we're ready to install event handler that initializes (runs) our application after the document is fully loaded.

Line

Ext.onReady(myNameSpace.app.init, myNameSpace.app);

says: When the document is fully loaded, run init method of myNameSpace.app in the scope of myNameSpace.app.

Then come title, end of head, body (empty for now) and closing tags.

That's all for minimal html file.

applayout.js

/**
  * Application Layout
  * by Jozef Sakalos, aka Saki
  * http://extjs.com/learn/Tutorial:Application_Layout_for_Beginners
  */
 
// reference local blank image
Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';
 
// create namespace
Ext.namespace('myNameSpace');
 
// create application
myNameSpace.app = function() {
    // do NOT access DOM from here; elements don't exist yet
 
    // private variables
 
    // private functions
 
    // public space
    return {
        // public properties, e.g. strings to translate
 
        // public methods
        init: function() {
            alert('Application successfully initialized');
        }
    };
}(); // end of app
 
// end of file

Fist lines of this file are comments that explain content of the file, author and another relevant information. Sure, your applications would run without any single comment line but remember: Always write your application as if you would write it for another. When you come back to your own code after a couple of months and you don't know what it does then remember the above rule and change your coding practices.

Then comes reference to blank image pointing to your own server instead of default extjs.com. You don't want to access extjs.com on each application load, do you?

Now we create our own namespace. The reason is to encapsulate all variables and methods in one global object to avoid any conflicts of variable names and unpredictable changes of their values by various functions should they be global. The name you choose is up to you.

The core of it, at last... We create property app of myNameSpace as the return value of the function that runs immediately.

If we run the following code

var o = function() {
    return {p1:11, p2:22};
}();

we're in fact creating anonymous function (function without name) that runs immediately after parsing (mind () after the function definition). The function returns object which is assigned to variable o. Our application uses the same logic.

You can put an initialization and private variables and/or private functions definitions between the beginning of the function and return statement but keep in mind: This code runs as a part of head when no html elements yet exist so any attempt to access them would result in an error.

On the other hand, the init function, that is just one of the methods returned by that anonymous function, runs after the whole document is fully loaded when the whole DOM structure is already available.

So far, so good. If you haven't made any mistake you get success alert when you navigate to http://yourserver.com/applayout/applayout.html, in another words, when you run your application.

Now comes most difficult part: To write something useful inside of this empty template.

Public, Private, Privileged?

Let's add some life to our application. Add the following line to applayout.html inside the body tag:

<div id="btn1-ct"></div>

It is empty div that will serve as the button container. Then add a couple of lines to applayout.js that it reads:

/**
  * Application Layout
  * by Jozef Sakalos, aka Saki
  * http://extjs.com/learn/Tutorial:Application_Layout_for_Beginners
  */
 
// reference local blank image
Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';
 
// create namespace
Ext.namespace('myNameSpace');
 
// create application
myNameSpace.app = function() {
    // do NOT access DOM from here; elements don't exist yet
 
    // private variables
    var btn1;
    var privVar1 = 11;
 
    // private functions
    var btn1Handler = function(button, event) {
        alert('privVar1=' + privVar1);
        alert('this.btn1Text=' + this.btn1Text);
    };
 
    // public space
    return {
        // public properties, e.g. strings to translate
        btn1Text: 'Button 1'
 
        // public methods
        , init: function() {
            btn1 = new Ext.Button('btn1-ct', {
                  text: this.btn1Text
                , handler: btn1Handler
            });
        }
    };
}(); // end of app
 
// end of file

Variables btn1 and privVar1 are private. That means that they cannot be accessed, they are even not visible, from outside of your application. The same is true for the private function btn1Handler.

On the other hand, btn1Text is public variable that is visible and can be accessed or changed from outside of app. (We will demonstrate it later.)

Function init is privileged in that that it can access both private and public variables or functions. In our example, it accesses public variable this.btn1Text and also private function btn1Handler. Function init is public in that that it can be called from outside.

Ok, let's run it. Have you got button in the upper left corner? Good. Click it. You got alert with privVar1=11, right? Private function can access private variables.

But something is wrong with second alert which says this.btn1Text=undefined that is not what was expected. The reason is that variable this inside of handler points to button and not to our application. Add scope:this to the button configuration that it reads:

btn1 = new Ext.Button('btn1-ct', {
      text: this.btn1Text
    , handler: btn1Handler
    , scope:this
});

and reload the page. Works, yeah?

Overriding public variables

Add the following code near the end of applayout.js so that it reads:

Ext.apply(myNameSpace.app, {
    btn1Text:'Taste 1'
});
 
// end of file

What the whole code does now? It first creates our application object and then changes (overrides) value of the public variable btn1Text. Run it to see that text displayed on the button changed.

It is good coding practice to put all texts used in application to public variables as they can be then easily translated to other languages without touching the original application code.

Of course, you should also put another values such as default dimensions, styles, etc., in another words, all customizable options into public variables. Then you won't need to browse through thousands of lines of the application code to find where to change color of something.

Overriding public functions

Let's change our code that is reads the following:

Ext.apply(myNameSpace.app, {
      btn1Text:'Taste 1'
    , init: function() {
        try {
            btn1 = new Ext.Button('btn1-ct', {
                  text: this.btn1Text
                , handler: btn1Handler
                , scope: this
            });
        }
        catch(e) {
            alert('Error: "' + e.message + '" at line: ' + e.lineNumber);
        }
    }
});
 
// end of file

What we're doing here? Just overriding init function with the exactly same code as it was before only enclosed in try/catch so we can handle errors, if any. We expect that it will run as before, or not? Run it to find out.

Yes, there is error saying that btn1Handler is not defined. It is because new function is trying to access private variable but it cannot. You see, original init is privileged so it has access to private space but new init hasn't. There is also aspect of safety in this: No code from outside, even if it tries to override privileged methods cannot get access to the private space.

To be continued...

I'm releasing this first part of the tutorial as I think that it can be useful as it is, nevertheless, I plan to continue with another examples.

  • This page was last modified 20:00, 26 August 2007.
  • This page has been accessed 2,140 times.