Home > ExtJS > Preparing Your ExtJS Environment

Preparing Your ExtJS Environment

April 5th, 2009

In my last post I said that ExtJS is a front-end widget system. No doubt you could use it to create an entire system, front to back, in nothing by ExtJS, but that’s not my project nor is what I plan to talk about in these posts. Which brings us to the first question you need to answer when setting up your ExtJS environment: what am I going to use as a back-end? There are probably lots of right answers to this question, and a great deal of debate over which one is more right, and I gleefully leave that fight for others. For my purposes, the answer to that question is merb (it’s like rails, but better), so if that’s not your platform of choice, you will have to make some adaptations of your own.

First things first, setup your application by whatever magical incantation is appropriate, in my case:

merb-gen app extjs_demo

Now we have a clean application all ready to go. Next you need to bring ExtJS into your codebase so you will have access to it. As ExtJS is 99% javascript, you will want to install in whatever directory your app will use as its document_root so that HTTP requests can get at it. In merb/rails, that directory is called public/. I recommend against using public/javascripts/, even though it’s right there calling out for javascript files. The way I see it, ExtJS is an external library, while public/javascripts/ is where you put your own application scripts, but reasonable minds can disagree.

Head on over to extjs.com and grab the latests release (2.2.1 as of this writing). Pay attention here… you want to unzip the file in its own directory named extjs-2.2.1 (or whatever version you downloaded). If you unzip the file directly into public/, you’re going to be sorry. Now create a symlink pointing to extjs-2.2.1 called “extjs”.

ln -s extjs-2.2.1 extjs

This symlinking strategy allows you to easily try out new releases of ExtJS and revert back without having to worry about blowing away old versions until you are ready.

Now you have ExtJS installed and can already do a great deal if you were to startup your empty app right this very second and access http://localhost:4000/extjs/docs/index.html with your trusty browser. Your framework may use a different port number (Rails defaults to 3000). With merb properly installed on my system, I can just startup the app from the merb root directory by running:

bin/merb

Your browser should show you the API docs just as if you had accessed them on the ExtJS website. This is going to be your number one place to learn the finner points of ExtJS, and now you have it with you so long as you have your application’s source. Handy for those times you don’t have internet access. If you’re using source control, now is a good time to commit :)

Next we face an important choice. As we build our application we are going to define different ExtJS subclasses (more on what that means in a later post). Those subclasses need to be loaded into your application via the familiar script tag. But there are two different ways our application can respond the script tags request:

  1. Serve static javascript files from public/
  2. Serve dynamic javascript files from a controller/view setup

Static files in public/ have the advantage of loading much faster, as they come directly off the file system and skip over the framework’s call stack. Dynamic files from a controller/view are dynamic, which allow the javascript to be custom tailored for the user’s needs. Both have their uses and after a lot of trial and experimentation, I determined the best approach is to use both. Okay, so I lied… there is no choice.

What we are going to do is define the various subclass methods in public/javascripts/. These files do not need to change on a per-user basis, so we get the benefit of the static load time. But any files that require dynamic generation will be done via a controller and a view. But before we go a step further we need to setup your application’s index page.

In my estimation, there are two ways to use ExtJS in your application. You can either use it as a widget set for things like buttons, dialog boxes, and grids in the way you might use jQuery UI. Or you can do everything in ExtJS. For the app I’m building at work, ExtJS powers the entire display of the administrative back-end. The setup I’ll show you today assumes that you’re entire app is going to be driven by ExtJS. If you think you’re going to be less whole-hog, don’t worry, many of the steps will be the same.

First things first, we need a root index page to work with. By default, I get a lovely No routes match the request: / error message when trying to access http://localhost:4000. There are lots of ways to setup an index page depending on your framework, all of which is beyond the scope of this post. What I did with merb was create a controller called “home” and added a route to connect “/” with “home/index”.

Next we need to get the view for home/index looking how we want. Many MVC frameworks use layouts to reduce code duplication between views — which is great — but for us, it’s actually a real problem. So I recommend you disable layouts for the home controller (in merb you just declare “layout false” in the controller file). Now head over to the view for home/index (in merb, it will be at app/views/home/index.html.erb). This file is going to serve as your loading point for all the ExtJS magic you need to make your application sing.

Now, add the following HTML right into the file:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Your ExtJS Application</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <link rel="stylesheet" type="text/css" href="/extjs/resources/css/ext-all.css">
</head>
<body>

  <!-- External Dependencies -->
  <script type="text/javascript" src="/extjs/adapter/ext/ext-base.js"></script>
  <script type="text/javascript" src="/extjs/ext-all-debug.js"></script>

  <!-- Application Runner -->
  <script type="text/javascript" src="/home/application.js"></script>

  <!-- App Specific Classes -->

</body>
</html>

Let’s look at the lines that may not seem immediately obvious:

<link rel="stylesheet" type="text/css" href="/extjs/resources/css/ext-all.css">

Loads the ExtJS master CSS file. This has all sorts of CSS definitions that make all the ExtJS widgets look super delicious.

<!-- External Dependencies -->
<script type="text/javascript" src="/extjs/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="/extjs/ext-all-debug.js"></script>

These two lines load up the ExtJS library itself into your application. Make sure you load them in the order specified here. Couple of important notes here. The first line is the adapter line, and I’m told it allows you to teach ExtJS to play nice with other JS frameworks like jQuery and Prototype. I haven’t played with any of that, so your mileage may vary if you go that direction, here we are using ExtJS with ExtJS. The second line is the monster library include and here you actually have two choices. In development mode, I always load ext-all-debug.js, because Firebug output is far more useful… but in production, you’ll want to use ext-all.js, which has been minified for quicker download to your clients. In a more advanced application, we’d have the view determine which file to send programatically, but we are going to take it slow.

<!-- Application Runner -->
<script type="text/javascript" src="/home/application.js"></script>

<!-- App Specific Classes -->

The Application Runner is the starter pistol of your ExtJS application… the thing which makes it go. We are going to setup a basic one in just a moment. Then under that is where your application specific ExtJS subclasses are going to be loaded. There aren’t any at present, but we will write one shortly and it’s good to have a place ready to put them.

For the Application runner you will need to add an application action to the home controller and indicate that it serves up javascript. In Merb:

  def application
    provides :js
    render
  end

Then create a view at app/views/home/application.js.erb and dump in the following:

Ext.BLANK_IMAGE_URL = '/extjs/resources/images/default/s.gif';
Ext.ns('demo');

// application main entry point
Ext.onReady(function() {

  var viewport = new Ext.Viewport({
    items: [
      {
        region:     'north',
        html:       '<h1 class="x-panel-header">Your Demo Application</h1>',
        autoHeight: true,
        border:     false,
        margins:    '0 0 5 0'
      },{
        region:     'center'
      }
    ]
  });
  viewport.show();

});

The first two lines of code set some global configuration. The first line there is a request from the fine folks at ExtJS to use your own locally hosted single blank pixel instead of theirs (it’s the least you can do). The next creates a namespace for the code you are going to be writing. I’ve chosen the highly descriptive “demo” as my namespace here, but I recommend using a short-hand version of your application. The big advantage of using a namespace is now you can define whatever classes you want without bumping into native javascript classes. All of the ExtJS base classes are namedspaced to “Ext”, so I recommend using something other than that.

Then comes the starter pistol:

Ext.onReady(function() {
  // code goes here
});

If you are familiar with jQuery, this is equivalent to:

$(document).ready(function(){
  // code goes here
});

What it does is ensure the code inside of the block is not executed until the entire page is done loading. Meaning all of the javascript libraries, CSS files, etc. If you try to execute your application code right away, you can’t be sure the environment is full prepped. Wrapping your code in the Ext.onReady method gives you the confidence everything is, well, ready.

Then lastly we’ve got this Ext.Viewport constructor with some configuration parameters passed into the constructor. Don’t worry about the specifics of the configuration at the moment, we’ll talk about Viewports in some other post. What’s important to know is that Viewports setup a full browser window environment to instantiate other components. It is the starting point of any full ExtJS application.

At this point you can save these files, startup your application and go to the index page. You should get a panel at the top that reads “Your Demo Application”. Congratulations, you’ve got an ExtJS application!

One last thing to do before we close down for the day. The Viewport there has application specific configuration variables, and as you will learn in the post on subclassing, that is indicator number one that we should create an ExtJS subclass. To do so, create a file at public/javascripts/demo.viewport.js (note, if you declared a different namespace than “demo” use that wherever I use “demo” in all of the following examples). In the file you just created, paste the following:

demo.viewport = function(config) {

  var base_config = {
    items: [
      {
        region:     'north',
        html:       '<h1 class="x-panel-header">Your Demo Application</h1>',
        autoHeight: true,
        border:     false,
        margins:    '0 0 5 0'
      },{
        region:     'center'
      }
    ]
  };

  Ext.apply(base_config,config);

  demo.viewport.superclass.constructor.call(this,base_config);

}

Ext.extend(demo.viewport, Ext.Viewport, {});

Update your application.js file to read:

Ext.BLANK_IMAGE_URL = '/extjs/resources/images/default/s.gif';

Ext.ns('demo');

// application main entry point
Ext.onReady(function() {

  var viewport = new demo.viewport()
  viewport.show();

});

And under “App Specific Classes” in the index.html file, add:

<script type="text/javascript" src="/javascripts/demo.viewport.js"></script>

Reload the index page and nothing should change. Except now we’ve got the static parts of the application being served from public/javascripts/ and the dynamic parts of the application from the home controller. With this basic framework we are ready to start learning about subclasses and how to organize you ExtJS code.

probonogeek ExtJS

  1. No comments yet.
  1. No trackbacks yet.