In this chapter, we will cover the basics of Ext JS and what it can do for us. If you're accustomed to the standard Web development, then you'll be excited when you learn about the elegance in the architecture of Ext JS, just as I was. Unlike other JavaScript libraries, Ext JS handles the messy foundation work for you, so with only a few lines of code, we can have a fully functional user interface.
In this chapter, we will cover:
Some JavaScript fundamentals which are key to understanding Ext JS code
What Ext JS does and why you'll love using it
How to get Ext JS and start using it in your Web applications
Creating a simple "hello world" example
Using "adapters" to allow Ext JS to co-exist with other JavaScript libraries
Taking advantage of AJAX technology
Displaying Ext JS Components in your own language
JavaScript is an object-based language. Every data item is an object. Numbers, strings, dates, and Booleans (true or false values) are all objects.
JavaScript variables reference the objects we assign to them. Think of a variable as a "pointer" to the object, not a "box" into which a value is placed. A variable assignment statement does not move any data. It simply changes where the variable is pointing to.
In JavaScript, functions are also objects, and may be assigned to variables and passed as parameters just the same as other objects. A function declaration is a literal in just the same way that a quoted string is a literal.
Consider the following example. A variable is assigned to a string and then a function.
var myVariable = "A string literal"; alert(myVariable); myVariable = function() { alert("Executing the function"); }; myVariable();
The variable myVariable
is set to reference (point to) a string literal which is then alerted to the user.
Then the variable is set to reference a function literal. That variable is then used to call that function. Appending the ()
causes the referenced function to be called.
This concept is central to your understanding of much of what follows. Functions will be passed as parameters into Ext JS methods to be called by Ext JS to handle user interface events or network communication (AJAX) events.
Ext JS also provides its API in an Object Oriented manner. This means that it does not simply provide a mass of utility functions; instead, mnemonically named classes are provided which encapsulate discrete areas of functionality. Functions are called as member methods of a class. All Ext JS widgets: grids, trees, forms, and so on are objects. For more information on this concept, see http://en.wikipedia.org/wiki/Object-oriented_programming.
It is important to remember that when a function reference is passed, it's only a pointer to a function object. If that function was a member method of an object, then this information is not included. If the function is to be executed as a member method of an object, then that information must be included when passing the function. This is the concept of scope, which will be very important in later chapters.
If that went a bit over your head, don't worry. Put a bookmark in this page, and refer to it later. It will be important!
JavaScript is an object-based language. Every data item is an object. Numbers, strings, dates, and Booleans (true or false values) are all objects.
JavaScript variables reference the objects we assign to them. Think of a variable as a "pointer" to the object, not a "box" into which a value is placed. A variable assignment statement does not move any data. It simply changes where the variable is pointing to.
In JavaScript, functions are also objects, and may be assigned to variables and passed as parameters just the same as other objects. A function declaration is a literal in just the same way that a quoted string is a literal.
Consider the following example. A variable is assigned to a string and then a function.
var myVariable = "A string literal"; alert(myVariable); myVariable = function() { alert("Executing the function"); }; myVariable();
The variable myVariable
is set to reference (point to) a string literal which is then alerted to the user.
Then the variable is set to reference a function literal. That variable is then used to call that function. Appending the ()
causes the referenced function to be called.
This concept is central to your understanding of much of what follows. Functions will be passed as parameters into Ext JS methods to be called by Ext JS to handle user interface events or network communication (AJAX) events.
Ext JS also provides its API in an Object Oriented manner. This means that it does not simply provide a mass of utility functions; instead, mnemonically named classes are provided which encapsulate discrete areas of functionality. Functions are called as member methods of a class. All Ext JS widgets: grids, trees, forms, and so on are objects. For more information on this concept, see http://en.wikipedia.org/wiki/Object-oriented_programming.
It is important to remember that when a function reference is passed, it's only a pointer to a function object. If that function was a member method of an object, then this information is not included. If the function is to be executed as a member method of an object, then that information must be included when passing the function. This is the concept of scope, which will be very important in later chapters.
If that went a bit over your head, don't worry. Put a bookmark in this page, and refer to it later. It will be important!
The Web 1.0 way of doing things has all of our code happening in succession—waiting for each line of the code to complete before moving on to the next. Much like building a house, the foundation must be complete before the walls can be built and then the walls must be complete before the roof is built.
With Ext JS, we can easily start working on the roof of our house before the foundation has even been thought about. Imagine the roof of our house is being built in a factory, while at the same time we are building the foundation, then the walls, and we come in when all of this is done and set the roof that has already been built on top of it all.
To visualize this, look at the following diagram. Contrast the linear assembly of the house on the left with the assembly on the right in which manufacture of the roof happens concurrently with the walls and foundation:
This introduces some things we're not used to having to cope with, such as the roof being complete before the walls are done. No longer are we forced to take a line-by-line approach to Web development.
Ext JS helps us out by giving us events and handlers to which we can attach our functionality. As described above, we can specify a function to be called later, when the walls of the house are built, which then sets the roof on top once this has happened.
This method of thinking about Web pages is hard for most people who have grown up in Web development. We must be aware of not only what our function does, but also when it does it. We might embed a function literal inside our code which does not run immediately, but just sits dormant until an event fires at some time in the future.
We will be working with the most recent release version of Ext JS which, at the time of writing, is the 3.x branch. However, the examples used in this book will be compatible with the 2.x branch unless specifically noted. The change from 1.x to 2.x was a major refactoring that included taking full advantage of the newly-created Component model, along with renaming many of the components to provide better organization. These changes have made the 1.x code mostly incompatible with 2.x, 3.x, and vice versa. An upgrade guide that explains in more detail what has changed is available on the Ext JS website:
http://www.extjs.com/learn/w/index.php?title=Ext_1_to_2_Migration_Guide
The 3.x branch is backwards-compatible with 2.x, so many of the examples in this book will work with both versions. The Ext JS development team is dedicated to making future releases backwards-compatible.
The Ext JS library started out as an extension to the moderately popular, yet very powerful Yahoo User Interface library, providing what the YUI library lacked: an easy-to-use API (Application Programming Interface), and real world widgets. Even though the YUI Library tried to focus on the 'User Interface', it didn't contain much that was useful right out-of-the-box.
It wasn't long before Ext JS had developers and open-source contributors chipping in their knowledge to turn the basic YUI extension into one of the most powerful client-side application development libraries around.
Ext JS provides an easy-to-use, rich user interface, much like you would find in a desktop application. This lets Web developers concentrate on the functionality of Web applications instead of the technical caveats. The examples given on the Ext JS website speak the loudest about how amazing this library is:
http://www.extjs.com/deploy/dev/examples/
One of the most striking examples is the Feed Viewer. This demonstrates the many aspects of Ext JS. However, it is a bit too complex to be used as a learning example. So for now, we can just revel in its brilliance. The following screenshot illustrates the familiar border layout with user-resizable regions, which you may notice being used in programs like email readers:
Another excellent example is the Simple Tasks task-tracking program, which utilizes a Google Gears database.
Over the course of this book, we will learn how to build Web interfaces as impressive as these.
Ext JS is not just another JavaScript library. It is a fully featured client UI library capable of creating dynamic, fluidly laid out user interfaces which are bound to structured data which itself is linked to server-side data sources. Ext JS can, however, work alongside other JavaScript libraries by using adapters. We'll see how to work with adapters later in this chapter.
Typically, we would use Ext in a website that requires a high level of user interaction—something more complex than your typical website, most commonly found in intranet applications. A website that requires processes and a work flow would be a perfect example, or Ext JS could just be used to make your boss gasp with excitement.
Ext JS makes Web application development simple by:
Providing easy-to-use cross-browser compatible widgets such as windows, grids, and forms. The widgets are already fine-tuned to handle the intricacies of each web browser on the market, without us needing to change a thing.
Interacting with the user and browser via the EventManager, responding to the user's keystrokes, mouse clicks, and monitoring events in a browser such as a window resize, or font size changes.
Communicating with the server in the background without the need to refresh the page. This allows us to request or post data to or from our web server using AJAX and process the feedback in real time.
I am sure I don't need to explain the pitfalls of browser compatibility. From the first time we create a DIV element and apply a style to it, it becomes apparent that it's not going to look the same in every browser unless we are very diligent. When we use Ext JS widgets, the browser compatibility is taken care of by the Ext JS library, so that each widget looks exactly the same in all supported browsers, which are:
Internet Explorer 6+
Firefox 1.5 + (PC, Mac)
Safari 2+
Opera 9 + (PC, Mac)
Chrome 1+
Events describe when certain actions happen. An event could be a user action such as a click on an element, or it could be a response to an AJAX call. When a user interacts with a button, there is a reaction, with not just one but many events happening. There is an event for the cursor hovering over the button, and an event for the cursor clicking on the button, and an event for the cursor leaving the button. We can add an event listener to execute some function when any or all of these events take place.
Listening for events is not strictly related to the user interface. There are also system events happening all the time. When we make AJAX calls, there are events attached to the status of that AJAX call to listen for the start, the completion, and possible failure.
The term AJAX (Asynchronous JavaScript and XML) is an overly-complicated acronym for saying that processes can take place in the background, talking to the server while the user is performing other tasks. A user could be filling out a form while a grid of data is loading—both can happen at the same time, with no waiting around for the page to reload.
Everything we will need can be downloaded from the Ext website, at http://www.extjs.com/products/js/download.php. Grab the Ext JS SDK (Software Development Kit), which contains a ton of useful examples and the API reference. Most importantly, it contains the resources that Ext JS needs to run properly.
Once you get the SDK file, uncompress it onto your hard drive, preferably in its own folder. My approach to folder naming conventions is based on the standard Linux structure where all libraries go into a lib
folder. So for the sake of the examples in this book, uncompress all of the files in the SDK into a folder named lib
.
After extracting everything from the SDK download file, your directory tree should look like this:
To make it easier when we upgrade our Ext library to the most recently-released version, let's rename the ext-3.2.0
folder to extjs
.
If your company is using source control, along with quality assurance testing, then sticking with a folder name based on the library version number might be more appropriate.
The SDK contains a version of Ext JS that has everything we need included in it, commonly called ext-all
. It also contains a version used for development referred to as the debug
version, which is what we will primarily use. The debug version makes it easier to locate errors in our code because it's uncompressed and will report back relevant line numbers for errors. When it's time to release our creation to the general public, we can switch our application to use the standard ext-all
, and everything will continue to work as it was.
Included in the SDK file are a specification of dependencies, documentation, example code, and more. The adapter
and resources
folders shown in bold are required for Ext to work properly; everything else is just for development purposes:
adapter:
Files that allow you to use other libraries alongside Ext JSdocs:
The documentation center (this will only work when run from a web server)examples:
Plenty of amazing and insightful examples, plugins, and extensionspkgs:
Packaged up Ext JS modules used when building Ext JSresources:
Dependencies of the Ext JS library, such as CSS and imagessrc:
The complete source code for Ext JStest:
The test suite for Ext JSwelcome:
Miscellaneous image files
When you're ready to host your page on a web server, the adapter
and resources
folders will need to be uploaded to the server in addition to the ext-all.js
and ext-all-debug.js files.
Before we can use Ext JS in our pages, we need to reference the Ext JS library files. To do this, we need to include a few of the files provided in the SDK download in the HEAD
portion of our HTML page. In our simple pages, we will not use a doctype. Ext JS supports running with no doctype (quirks mode), across all browsers.
<html> <head> <title>Getting Started Example</title> <link rel="stylesheet" type="text/css" href="lib/extjs/resources/css/ext-all.css" /> <script src="lib/extjs/adapter/ext/ext-base.js"></script> <script src="lib/extjs/ext-all-debug.js"></script> </head> <body> <!-- Nothing in the body --> </body> </html>
The path to the Ext JS files must be correct and is relative to the location of our HTML file. These files must be included in the order shown. A theme CSS file may be included after the ext-all.css
file to customize the look of the UI.
We have included the following three files, which Ext JS requires to run in our page:
ext-all.css:
A stylesheet file that controls the look and feel of Ext JS widgets. This file must always be included as-is, with no modifications. Any changes to the CSS in this file would break future upgrades. If we decide that the look and feel of Ext JS needs to be adjusted, another stylesheet containing the overrides should be included after theext-all.css
file.ext-base.js:
This file provides the core functionality of Ext JS. It's the foundation upon which Ext JS builds its capabilities, and provides the interface to the browser environment. This is the file that we would change if we wanted to use another library, such as jQuery, along with Ext JS.ext-all-debug.js/ext-all.js:
All of the widgets live in this file. The debug version should always be used during development, and then swapped out for the non-debug version for production.
Once these files are in place, we can start to actually use the Ext JS library and have some fun.
Ext JS needs to use a spacer image, a 1 pixel by 1 pixel, transparent, GIF image to stretch in different ways, giving a fixed width to its widgets. When run on modern browsers, Ext JS uses an image encoded as a data URL—the URL begins with data: not http:. But on legacy browsers, the default URL references a GIF at the extjs.com website. This may not always be accessible or desirable. We can change this to reference the image on the local server using the following code:
if (Ext.BLANK_IMAGE_URL.substr(0, 5) != 'data:') { Ext.BLANK_IMAGE_URL = ' lib/extjs/ resources/images/default/s.gif'; } Ext.onReady(function(){ // do other stuff here });
You're probably wondering why we need a spacer image at all. The user interface of Ext JS is created using CSS, but the CSS needs underlying HTML elements to style so that it can create the look and feel of the Ext JS components. The one HTML element that lays out inline, and is sizeable in both dimensions across all browsers is an image. So an image is used to size portions of the Ext JS Components. This is a part of how Ext JS maintains its cross-browser compatibility.
Now that we've added the Ext JS library to our page, we can start writing the code that uses it. In the first example, we will use Ext JS to display a message dialog. This might not sound like much, but we need to start somewhere.
We can play with some Ext JS code by adding a script element in the head of our document, right after where the Ext JS library has been included. Our example will bring up an Ext JS style alert dialog:
<html> <head> <title>Getting Started Example</title> <link rel="stylesheet" type="text/css" href="lib/extjs/resources/css/ext-all.css" /> <script src="lib/extjs/adapter/ext/ext-base.js"></script> <script src="lib/extjs/ext-all-debug.js"></script> <script> if (Ext.BLANK_IMAGE_URL.substr(0, 5) != 'data:') { Ext.BLANK_IMAGE_URL = 'lib/extjs/resources/images/default/s.gif'; } Ext.onReady(function(){ Ext.Msg.alert('Hi', 'Hello World Example'); }); </script> </head> <body> <!-- Nothing in the body --> </body> </html>
We're not going to cover exactly what our example script is doing yet. First, let's make sure that the Ext JS library is set up properly by running this basic example. If we open up our page in a web browser, we should be able to see an alert message like the one shown as follows:
Just like a "real" dialog, we can drag it around, but only within the constraints of the page. This is because this isn't a real dialog; it's a collection of DIV tags and images put together to imitate a dialog. We can also see that the Close and OK buttons get highlighted when we move the cursor over them—not bad for one line of code! Ext JS is taking care of a lot of the work for us here, and throughout this book, we'll see how to get it to do much more for us.
Note
In this example, we start with an empty document which contains no HTML. Ext JS does not require any pre-existing markup, and will create it as needed. However Ext JS also has the ability to import pre-existing markup, and use it as the basis for new widgets. This will be discussed in Chapter 2.
Let's take a look at the example code, which we just ran:
Ext.onReady(function(){ Ext.Msg.alert('Hi', 'Hello World Example'); });
After referring back to our discussion of JavaScript objects earlier in this chapter, you can see that this code fragment passes a function literal as a parameter to Ext.onReady.
The Ext.onReady function accepts a function as its first parameter. It will call that function when the page has fully loaded, and the HTML document is ready to be manipulated. If you pass a function to Ext.onReady
when the document is already fully initialized, it will be called immediately.
That passed function calls a method upon the Ext.Msg object which is a pre-initialized object which Ext JS provides to show simple dialogs.
The Ext.Msg.alert function displays a dialog with the first parameter as the title and the second parameter as the message in the body.
Ext JS can only render widgets when the HTML document has been fully initialized by the browser. All Ext JS pages must only begin accessing the document within an Ext.onReady call.
We could have written the code like this:
var mainFunction = function(){ Ext.Msg.alert('Hi', 'Hello World Example'); }; Ext.onReady(mainFunction);
In this version, we can see more easily that it is a function reference which is passed to Ext.onReady
. It's slightly more longwinded this way, but while still a beginner, this may be a useful style for us to use.
If the library is not set up correctly, we might receive an'Ext' is undefined error.
This message means the Ext JS library was not loaded. Usually, this is caused by having an incorrect path to one or more of the Ext JS library files that are included in our document. Double-check the paths to the included library files, and make sure they are pointing to the right folders and that the files exist. If everything is in its correct place, we should see an adapter
folder along with the files ext-all.js
and ext-all-debug.js
in our lib/extjs
folder.
Another common problem is that the CSS file is either missing or is not referenced correctly, which will result in a page that looks awkward, as shown in the following example:
If this happens, check to make sure that you have extracted the resources
folder from the SDK file, and that your paths are correct. The resources
folder should reside under the lib/extjs
folder.
The best way to debug failures like this is to use the Firefox browser with the Firebug debugging add-on. This provides a display of the status of all network requests. If any fail, then they will be highlighted in red, as follows:
When Ext JS was first being developed (initially called "yui-ext"), it required the YUI library to be in place to do the behind-the-scenes work. Later on, Ext was given the option of using two other frameworks—jQuery or Prototype with Scriptaculous (Protaculous).
This means that if we were previously using other libraries or if we felt some other base library was somehow superior or better suited our needs, we could continue using that library in conjunction with Ext JS by using the appropriate adapter. Either way, Ext JS functions the same, and all of the components will work identically, no matter which adapter we choose.
Ext JS also has its own adapter which interfaces directly to the environment. If you have no preference for another library or framework, then go with the Ext JS built-in the adapter.
To use an adapter, we must first include the external library that we want to use, and then include the related adapter file that is located in the adapter's folder of the Ext JS SDK. Our example code uses the Ext JS adapter. To use any of the other libraries, just replace the default Ext JS adapter script include line with the lines for the specific libraries, as shown below:
Default Ext JS adapter:
<script src="lib/extjs/adapter/ext/ext-base.js"></script>
For jQuery, include the jQuery library file in the head of the document, along with any plugins you might use:
<script src="lib/jquery.js"></script> <script src="lib/jquery-plugins.js"></script> <script src="lib/extjs/adapter/jquery/ext-jquery-adapter.js"> </script>
For YUI 2, include these files in the head. The utilities
file is located in the build/utilities
folder of the YUI 2 library download:
<script src="lib/utilities.js"></script> <script src="lib/extjs/adapter/yui/ext-yui-adapter.js"></script>
For "Prototype + Scriptaculous", include the Prototype library, along with the Scriptaculous effects in the head:
<script src="lib/prototype.js"></script> <script src="lib/scriptaculous.js?load=effects"></script> <script src="lib/extjs/adapter/prototype/ext-prototype-adapter.js"></script>
After the adapter and base libraries have been included, we just need to include the ext-all.js
or ext-all-debug.js
file.
Ext JS Components can be displayed in our specific language, and currently there are over 40 translations (unfortunately, Klingon is not yet available). All of these translations are created by the community—users like you and I who have the need to use Ext JS Components in their own native language. The included language files are to be used as a starting point. So we should take the language file we want to use and copy it to our lib
folder. By copying the language file to our lib
folder, we can edit it and add translated text for our custom components without it being overwritten when we upgrade the Ext JS library files.
There are three scenarios for localization that require three separate approaches:
English only
A single language other than English
Multiple languages
This requires no modifications to the standard setup, and there are no extra files to include because the English translation is already included in the ext-all.js
file.
The second option requires that we include one of the language files from the build/locale
folder. These language files are named to comply with the two letter ISO 639-1 codes, for example: ext-lang-XX.js
. Some regional dialects are also available, such as a Canadian version of French and British version of English. This option works by overwriting the English text strings present in the ext-all.js
file, so it should be included after all of the other library files, as shown below:
<link rel="stylesheet" type="text/css" href="lib/extjs/resources/css/ext-all.css" /> <script src="lib/extjs/adapter/ext/ext-base.js"></script> <script src="lib/extjs/ext-all-debug.js"></script> <script src="lib/extjs/build/locale/ext-lang-es.js"></script>
I have included the Spanish translations for this example. Let's see what our test page looks like now:
Elements that are part of the UI have been localized—these generally include calendar text, date formats, error messages, tool tip info messages, paging info, and loading indicators. Messages that are specific to your application, such as the Hi title and Hello World Example text, will need to be translated and added to our copy of the ext-lang-XX.js
file (where 'XX' is your two letter language code) or added to a new language file of your own. Another method is to create a language file of our own with just the additions and changes we need; this leaves us prepared for upgrades and fixes in the primary language file.
The third method of switching between different languages is basically the same as the second. We would just need to add some server-side scripting to our page to enable the switching between language files. Unfortunately, switching between languages cannot be done entirely dynamically; any component that has already been created must be re-created to switch languages. In other words, we can't do it entirely in real time and watch it happen on the screen.
If you have a problem which cannot be solved by reading this book, then there are several sources of help available at the Ext JS website.
The API documentation contains information about every class and every method in the library. This is not the regular API documentation we have become used to with many JavaScript libraries which simply informs you that a class exists, and that a method exists.
Classes are fully described, and all configuration options, properties, methods, and events are listed with each one being expandable and having a full description of its purpose and usage. It is also a great example of a rich Ext JS application:
The FAQ contains solutions for hundreds of issues which real-world Ext JS users have encountered in the past. This is the second line of help:
The online community for Ext JS is full of very knowledgeable people, and often, the Ext core developers are answering questions on the forum. The forum is the place to go to pose your question for assistance if the answer cannot be found in this book, in the API docs, or in the FAQ. The API docs and the FAQ are actively maintained by volunteers, and are updated in response to frequent forum questions.
If you run into problems, or run up against a wall, a search of the forum is likely to yield what you are looking for. I would suggest using the Google forum search tool that is available in the Learn section of the Ext JS website.
In this chapter, we have covered the basics of what we need to do to get Ext JS up and running, and what a simple script looks like. It's easy to miss a minor detail and get stuck with an error message that makes no sense. But now, you should be prepared to conquer any initial errors that you might come across.
The example we created showcases what Ext JS excels at: providing the user interface. We only used dialogs, but, as you now know, a few lines of code are all that are needed to display an Ext JS widget. The main goal of this chapter was to get Ext JS installed and working, so we can start creating some really sweet widgets and web applications. In the following chapter we will learn how to create more functional widgets, and how to configure them to behave exactly as we require.