Sencha Inc. | HTML5 Apps

Getting Productive

Published Dec 27, 2010 | The Sencha Dev Team | Tutorial | Medium
Last Updated Jul 11, 2011

This Tutorial is most relevant to Ext JS, 2.x, 3.x.

Using Widgets

In addition to a core javascript library, ExtJS also includes one of the richest sets of Javascript UI widgets available today. We will take a look at a few of the widgets that people use most commonly and how easy they are to work with.

MessageBox

Rather than a boring "Hello World" message box, let's add a little twist. Let's create some code to show the text of the paragraph that was clicked in a message box.

Ext.onReady(function() {
    var paragraphClicked = function(e) {
        var paragraph = Ext.get(e.target);
        paragraph.highlight();
 
        Ext.MessageBox.show({
            title: 'Paragraph Clicked',
            msg: paragraph.dom.innerHTML,
            width:400,
            buttons: Ext.MessageBox.OK,
            animEl: paragraph
        });
    }
    Ext.select('p').on('click', paragraphClicked);
});

There are a couple of concepts being shown here that are worth discussing. In the first line, we are now creating a local variable named paragraph that will hold a reference to the Element representing the DOM node that was clicked (in this case we know it will always be a paragraph since our click event is only associated with <p> tags). Why are we doing this? Well, looking ahead for a moment, we will need a reference to the Element to highlight it, and we'll also use the same Element for some of the MessageBox parameters. In general, it is bad practice to make the same function call multiple times to retrieve the same value or object reference, so by assigning it to a local variable and reusing the variable, we are being good object-oriented developers!

Now, on to the MessageBox call, which demonstrates the other new concept for us to discuss. At first glance, this may look simply like a list of parameters being passed to a method, but if you look closely, there is a very specific syntax. What is actually being passed to MessageBox.show() in this case is only one parameter: an object literal that contains a set of properties and values. In Javascript, an object literal is a dynamic, generic object that is created anytime you use the { and } characters surrounding a list of name/value properties, and the format for those properties is [property name] : [property value]. You'll see this pattern used extensively throughout Ext, so you should learn it well!

Why use an object literal? The main reason is flexibility. New properties can be added or removed from the object literal at any time, or defined in any order, while the method signature (the number and types of parameters expected by a method) never has to change. It also makes it far more convenient from the end developer's perspective when using methods with many optional parameters (as in the case of MessageBox.show). For example, let's say that a fictional method foo.action has four optional parameters, but you only need to pass one of them. In this case, your code might look like this: foo.action(null, null, null, 'hello'). However, if that method instead took an object literal, the code would look like this: foo.action({ param4: 'hello' }). Much easier to use, much more readable.

Grid

The grid is one of the most popular widgets in Ext, and usually the first one that people want to see, so let's take a look at how easy it is to get a basic grid up and running.
This example uses the same files as the Essentials Tutorial. First, replace the body of your ExtStart.html HTML file with one div with the id "grid-example". Then, replace any existing code you have in ExtStart.js so that it looks like this:

Ext.onReady(function() {
    // sample static data for the store
    var myData = [['Apple',29.89,0.24,0.81,'9/1 12:00am'],
		['Ext',83.81,0.28,0.34,'9/12 12:00am'],
		['Google',71.72,0.02,0.03,'10/1 12:00am'],
		['Microsoft',52.55,0.01,0.02,'7/4 12:00am'],
		['Yahoo!',29.01,0.42,1.47,'5/22 12:00am']
    ];
 
    // create the data store
    var ds = new Ext.data.ArrayStore({
        fields: [
           {name: 'company'},
           {name: 'price', type: 'float'},
           {name: 'change', type: 'float'},
           {name: 'pctChange', type: 'float'},
           {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
        ]
    });
 
    // manually load local data
    ds.loadData(myData);
 
    // create the colum Manager
    var colModel = new Ext.grid.ColumnModel([
    	    {header: 'Company', width: 160, sortable: true, dataIndex: 'company'},
            {header: 'Price', width: 75, sortable: true, dataIndex: 'price'},
            {header: 'Change', width: 75, sortable: true, dataIndex: 'change'},
            {header: '% Change', width: 75, sortable: true, dataIndex: 'pctChange'},
            {header: 'Last Updated', width: 85, sortable: true,
                renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
    ]);
 
 
    // create the Grid
    var grid = new Ext.grid.GridPanel({
        store: ds,
        colModel: colModel,
        height: 300,
        width: 600,
        title: 'My First Grid'
    });
 
    // render the grid to the specified div in the page
    grid.render('grid-example');
});

While this looks like a lot, it is really only seven lines of code in total!

  • The first line of code creates an array of data to be displayed in the grid. In real projects, you would likely load this data from some dynamic source like a database or web service.
  • Next, we create and load a data store, which will tell the underlying Ext library how to read and format the data.
  • Next, we define our column model which simply allows us to set up configuration options for each column of the grid.
  • Lastly, we create the grid widget, passing in the data store and column model and finally render it.

How easy was that? If all went well, you should end up with something that looks close to this:

Image:IntroToExt_grid.gif

Of course, there will probably be some details about this code that you may not fully understand at this point. The point of this example is to show how it's possible to create an extremely rich, visually-complex user interface component with very few lines of code—learning the details will be left as an exercise for the reader. There are many resources to help you with learning the grid, including the interactive grid demos and the grid API documentation.

And Many More...

We've only seen the tip of the iceberg here. There are literally dozens of UI widgets to choose from in Ext, including automatic page layouts, tabs, menus, toolbars, dialogs, a tree view and many more. Please explore the examples section of the API documentation for a glimpse of everything that's available.

Using Ajax

Once you have your page created and you know how to interact with it through Javascript, you'll probably want to know how to get data to and from a remote server, most commonly to load and save data from a database on the server. Doing this asynchronously via Javascript without reloading the page is known commonly as Ajax, and Ext has excellent Ajax support built right in. For example, a common goal is to handle a user interaction, post something to the server asynchronously, then update an element of the UI in response to the action. Here's an example of a very simple HTML form containing a text input field, a button, and a div used to display a message (Note: you can add this code to ExtStart.html if you'd like to follow along, but you'll have to have access to a web server in order to run the server code below):

<div id="msg"></div>
Name: <input type="text" id="name" /><br />
<input type="button" id="okButton" value="OK" />

Next, we'll add the Javascript required to get our data and post it to a server-based process (replace any existing code in ExtStart.js with this):

Ext.onReady(function(){
	Ext.get('okButton').on('click', function(){
		var msg = Ext.get('msg');
		msg.load({
			url: [server url], // <-- replace with your url
			params: 'name=' + Ext.get('name').dom.value,
			text: 'Updating...'
		});
		msg.show();
	});
});

(Note: when you check this example, open the page requesting it to the web server, that is, using http:// and not file:// in the URL.)

Hopefully the general pattern is starting to look familiar by now! The code is wrapping the okButton input with an Element object and attaching an anonymous function that will handle the event if anyone clicks on the button. Inside the click handler, we're using a special class built into Ext called the UpdateManager—this class makes sending an Ajax request, receiving a response and updating another Element extremely trivial. The UpdateManager can be used directly, or as we're doing here, it can be accessed via the Element that we want to update (in this case the 'msg' div) using the Element.load method. When Element.load is used, the server's response automatically replaces the innerHTML of the Element. Simply pass it the url to the server-based process that will handle the request, the querystring parameters to process (in this case passing in the value of the 'name' field) and the text to display in the Element's innerHTML while the request is being processed. Show the msg div (since it starts hidden by default) and that's it! Of course, as with most things in Ext, there are many more UpdateManager options supported, as well as different ways to process Ajax requests in different situations, but this shows how easy it is to get a basic example up and running.

The last piece of the Ajax puzzle is the process on the web server that actually handles the request and returns a response to the page. This process could be a server page, a servlet, an HTTP handler, a web service, even a Perl or CGI script—just about anything that can reside on a web server and process HTTP requests. Unfortunately, because of this variety there is no way to give a standard example that would cover all possibilities. Here are some examples in a few common languages to hopefully get you started (this code simply echoes whatever was passed from the 'name' field back to the client with 'From Server: ' added at the beginning, and that gets written to the 'msg' div):

Django

from django.http import HttpResponse
 
def ajax_request(request):
    return HttpResponse('From Server: %s' % request.POST.get('name', 'nada'))

PHP

&lt;?php if(isset($_POST['name'])) {
		echo 'From Server: '.$_POST['name'];
	}
?&gt;

Perl

#!/usr/bin/perl
use strict;
use warnings;
use CGI;
 
my $Query = new CGI;
 
print $Query->header();
print "Hello from : ".$Query->param('name');
 
exit;

ASP.Net

protected void Page_Load(object sender, EventArgs e)
{
	if (Request.Form["name"] != null)
	{
		Response.Write("From Server: " + Request.Form["name"]);
		Response.End();
	}
}

ColdFusion

<cfif StructKeyExists(form, "name")>
    <cfoutput>From Server: #form.name#</cfoutput>
</cfif>

JSP

From Server: ${param.name}

Servlet

protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException{
		response.getWriter().println(request.getParameter("name"));
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
	doGet(request,response);
}

Oracle PLSQL / Mod_PLSQL

htp.p('From Server '||name);

The real challenges when dealing with Ajax processing involve all of the plumbing code required to properly process and format real structured data on the server. There are several formats to choose from that people use commonly (most often either JSON or XML). There are also many language-specific libraries available to deal with Ajax processing that can work well with Ext, as Ext is language-neutral with regard to the server. As long as the result is sent to the page in the proper data format, Ext does not care what happens on the server!

Share this post:
Leave a reply

Written by The Sencha Dev Team

Commenting is not available in this channel entry.