Archive for the ‘ExtJs’ Category

Ext Scheduler

Monday, February 8th, 2010

A few weeks ago, Mats Bryntse (mankz on the ExtJS forums) asked me if I would be interested in taking a look under the hood of his Ext Scheduler application. There has been a great deal of buzz in the ExtJS community over his tool, so I jumped at the chance to peek into his source code. We’ve never actually met in person, but Mats seems like a good guy and he has a lot of good insight on the ExtJS forums. Apparently Mankz is also a DJ; I did not know that!

Disclaimer: Mats granted me a free license to use the tool in exchange for my review.

After unzipping the source code, I poked through a few of the examples. At first glance I was very impressed! The download came packaged with six demos, each of which utilizes different ExtJS features and gathers data via different sources (eBay, Google Calendar, among others). My only immediate complaint was that the API documentation wasn’t included in the ZIP file. It is however freely available on the Ext Scheduler website here.

Let’s Build Something Fun!

Rather than just saying what the Ext Scheduler does… let’s build something! Since Ext Scheduler’s website already has a handful of examples, I’d like to try building something new — let’s use the Twitter API and map when our tweets are posted.

A quick note: I didn’t realize something important until I was almost done with this application – the Twitter API doesn’t allow you to grab tweets based on a given time frame. You’re only allowed to grab the last X tweets… which I think is pretty lame. Had I know that before starting this application, I would have chosen a better example. *Facepalm!*

My journey through the Ext Scheduler started with a quick look through the API docs. The basis for the entire application is the Sch.SchedulerPanel() class, which is an extension of the Ext.grid.GridPanel(). If you read the API docs for this class, you’ll learn that it depends on two data stores: the first (“Store”) defines the various categories/rows for your application, while the other (“EventStore”) defines the events displayed on our schedule.

For my sample application, the “Store” will consist of a single Twitter user and the “EventStore” will be filled with this user’s 50 most recent Tweets. Thus, my application only has one row on the grid (boring, I know). I chose to display my grid as a 24 hour day so we can see our user’s Twitter activity over the course of a single day. Toolbar buttons allow us to move forward/backward by day. (Since the Twitter API doesn’t take start/end date parameters, this functionality is somewhat pointless.)

Take a moment now and try my sample application. We’ll explore it in more detail below, but see the source code here.

Learning Curve

My only real complaint with the Ext Scheduler code is the fact that there’s a slight learning curve. The examples provided in my ZIP folder are great, but there’s so much going on in each demo that it’s hard to figure out the basics. It took me the better part of a day to get my application working, so be prepared for a little bit of frustration.

Don’t get me wrong – this is an awesome tool, and I had the same complaints about ExtJS when I first started too. As such, I’m hoping this review can be a step-by-step demonstration on how to get started.

Step One: Define Your Categories

The “CategoryStore” is used for our left-hand grid labels – the entities to which the events are associated. In some of the other Ext Scheduler examples, the “Categories” were often people; the “Events” were often meetings or other appointments.

I started my application by prompting the user for their Twitter username. If you open my source file, you’ll see that I take the user’s input and insert it as a new data record into my TwitterApp.Scheduler.categoryStore (an Ext.data.JsonStore()). That was easy!

Next, I call the init() method on my TwitterApp.Scheduler object (a generic literal), which calls a series of other methods. In essence, here’s what they do:

  • Set this.start and this.end (values needed to properly display data in our schedule)
  • Create and load our “EventStore” (we’ll come back to this in a moment)
  • Create the scheduler grid and render it to the UI

Step Two: Define Your Events

As I just mentioned, we need to create and load the event data to display on our schedule. See the following code:

Ext Scheduler Demo

Our “EventStore” is another simple Ext.data.JsonStore() object; however, I’m pulling the data for this store from the Twitter API (based on the supplied username).

Take note of the “start” and “end” base parameters on this store. Although Twitter doesn’t really need them (which is why this example kinda sucks), the Ext Scheduler classes do! If you don’t add these parameters you’ll get an error!

When this store finishes loading (see my LOAD event), I manually set the “EndDate” property for each record because Ext Scheduler needs this information.

Step Three: Create the UI

Once we have our categories and events defined, we have the data we need to display the Ext Scheduler UI.

The Sch.SchedulerPanel() class is an extension of the ExtJS GridPanel(). The only things we really need to be aware of are the autoViews property and the eventTemplate since they’re the two things which really affect the appearance of our tool.

For the autoViews, you have your choice of displaying the grid by days/week, hours/day and a few other options. Since we’re using Twitter, I thought hours/day was most appropriate.

For the eventTemplate, it’s important to create an Ext.Template() object that means something to your users. Looking at the other examples of Ext Scheduler, you might see the name of the event, its start/end times, or other descriptive information. My example isn’t as cool… but you get the idea.

The only other thing I should point out is that your users will probably want a way to change the date range displayed by our scheduler grid. I added “Previous” and “Next” buttons which essentially alter the start/end date and reload our “event” data.

Step Four: Brag about your tool!

As I already pointed out, the Twitter API was a terrible choice for this demo because it doesn’t allow me to search for tweets by a selected date range. It was also a bad example because tweets don’t have start/end dates. Note to self: choose better examples next time!

Overall, my impression is that the Ext Scheduler will be an invaluable tool for most developers working with “events”. It’s easy to work with, offers an impressive set of features and should impress a lot of end-users. I would encourage everyone to check out the other Ext Scheduler examples and see for yourself!

JavaScript Tabs: ExtCore vs jQuery UI

Thursday, January 21st, 2010

A while back, I built a website for a client using jQuery 1.3 because I needed a slide-show widget for the homepage. More recently I’ve been using ExtCore for small website widgets – mainly because I’m a bigger fan of ExtJS than jQuery. (ExtCore also didn’t exist at the time I built that website).

Long story short, this particular client (a restaurant) asked me to add some new content to their menu. Rather than expecting the user to scroll down a lengthy list of mouthwatering lunch options, I suggested that we add tabs to the menu in order to logically separate the menu items.

Since I already had jQuery 1.3 running the slide-show on this website I simply decided to build the menu tabs in jQuery to maintain consistency. But I was suddenly struck by an idea: why not compare how ExtCore and jQuery UI create tabs from HTML markup!

ExtCore

ExtCore can be downloaded from the ExtJS website, and an online demo of the simple tabs can be seen here.

The first step to building tabs from HTML markup using ExtCore is to reference ext-core.js in your page header. You also need to include the tabs.css file and the “images” folder containing the necessary 5 background images. (These can be found under “/examples/tabs/” of your ExtCore download ZIP.)

Note: I’m using ExtCore 3.0, although I believe 3.1 is available for download.

Next, we need to add the appropriate HTML markup for our tabs. Here’s a quick example.

ExtCore HTML Markup

As you can see from the picture above, ExtCore takes a wrapping DIV element (class “tab_container”) and converts a nested unordered list into the tabs. Subsequent child DIV elements contain the markup for each tab’s content. (The source code in this example is taken directly from the ExtCore tab example.)

The only thing to notice is that each DIV element has a CSS class assigned to it – these classes are essential to proper tab theming. The DOM ID properties are used to click back-and-forth between tabs.

Lastly, you need to include a JavaScript snippet which converts your HTML markup into a fancy tabbed widget:

ExtCore JavaScript Code

jQuery UI

jQuery UI has a tab widget which is dependant on the larger jQuery library. An online demo of their tab widget can be seen here.

The first step to using tabbed content with jQuery is to reference:

  • jquery-1.3.2.min.js
  • jquery-ui-1.7.2.min.js

Your file versions may differ (I think jQuery 1.4 was just released), but these are the versions I’m using. I’m also using the “smoothness” theme – for some reason jQuery UI would not allow me to download the package without specifying a theme. (That may affect my analysis for speed in the next section.)

You will also need to include the CSS file and images folder included with your download of jQuery UI. In my case, it’s jquery-ui-1.7.2.css and an “images” folder containing 13 background images.

Next, write your HTML markup:

jQuery HTML Markup

Compared to ExtCore, jQuery UI expects less HTML markup as we lose several layers of nested DIV elements. The most obvious difference between jQuery UI and ExtCore is probably that jQuery UI doesn’t need the extra CSS classes applied to the DIV elements.

Next, we add our JavaScript snippet:

jQuery JavaScript Code

Again, jQuery UI expects less code to generate the tabbed widget.

A Deeper Look

Let’s take a look at the file sizes for each library. This is about as un-scientific a study as it can get; I’m using Firebug’s “Net” tab to grab file size and download speed numbers. These numbers will probably be different for you because of any number of factors… but you get the idea.

As I already mentioned, ExtCore requires 1 JavaScript file, 1 CSS file and only 5 background images:

  • ext-core.js (78.9 KB, 156ms)
  • Ext.tabs.css (1.3 KB, 147ms)
  • 5 png files (2.8-2.9 KB each, average 107ms)

Combing the file sizes and their download times (on my home network), you get a total of roughly 94.7 KB taking 838ms.

jQuery UI requires 2 JavaScript files, 1 CSS file and 13 background images (again, with the “smoothness” theme):

  • jquery-1.3.2.min.js (55.9 KB, 116ms)
  • jquery-ui-1.7.2.min.js (188.1 KB, 221ms)
  • 13 png files (22.3 KB total*)

*Something interesting I noticed about the jQuery UI tabs is that my page only seemed to load 5 of the 13 background images, totaling something like 605 bytes and a total of 684ms. Perhaps someone more familiar with jQuery can explain that to me… I didn’t dig deep enough to figure out what was going on, but I’ll base my total on what Firebug says. I’m guessing that I’m not using all of the CSS background images for this theme.

Overall, that brings jQuery UI tabs to a total of roughly 245 KB taking 1021ms.

What Does That Even Mean?

According to my inaccurate, quasi-scientific study it appears that ExtCore requires slightly more code than jQuery UI. On the other hand, ExtCore also appears to be downloaded by my browser more quickly than jQuery UI. In reality, those numbers probably offset each other as the extra markup required by ExtCore increases the HTML file size. The fact that I’m using a theme on jQuery UI probably also has a slight impact on performance.

Which do I prefer?

In essence, both libraries create tabbed widgets from the same basic HTML markup – though the differences are significant enough that they’re not cross-compatible.

Judging both frameworks as they stand in my examples, I will say that I like the conciseness (is that a word?) of jQuery with regards to both HTML markup and JavaScript code. But I also like that ExtCore requires fewer files. As someone who uses the larger ExtJS framework a great deal, I’ll say that I am very likely to choose ExtCore over jQuery UI most days of the week.

Are there any ExtCore or jQuery UI users out there? What do you think?

ExtJS Unit Testing now on Google Code

Thursday, December 17th, 2009

Although I’ve been meaning to do this for a while now, I finally released the ExtJS Unit Testing platform as an open source project on Google Code!

I’ve been talking about the need for a solid JavaScript unit testing platform for a while, specifically in relation to ExtJS. I gave a presentation on the subject a few months ago and have received some great feedback from the ExtJS community. I encourage you to take a look – I find it extremely helpful in my own day-to-day development.

See the interactive demo here.

Although I’ve been involved with several projects in the past, this is the first open source project that I have started on my own – and I had to stumble my way through the SVN setup. As ExtJS 3.x was released under the GPL v3 license, the ExtJS licensing team advised me to use the same license for this project.

If anyone is interested in contributing (or just wants to submit bug/feature requests) please don’t hesitate to contact me.

A Customized ExtJS Toolbar

Wednesday, December 2nd, 2009

The ExtJS grid is probably the most often used widget in the entire ExtJS library. The Ext.grid.GridPanel() object allows the developer to neatly display JSON or XML data returned from the server with little coding effort.

I’ve been working on an application for some time that necessitates changes to my grid’s toolbar depending upon several factors. The challenge that I’ve run into is that the default Ext.Toolbar() object is not very helpful when you try to show/hide options which are not specifically grouped.

For example, let’s say that you have a layout like the one pictured below. This particular layout allows the user to manage a list of physical locations and group them into categories.

ExtJS Toolbar Extension

As you can see, the grid has several top-level UI elements: a drop-down menu, a combo-box and several generic buttons. Our drop-down menu also has multiple options for the user to select (add/remove, etc).

This application requires that certain options are only visible when the grid is in its default (or ‘root’) view. Other options become visible (or hidden) when the grid is filtered by clicking on a category in the tree or by selecting a previously saved search algorithm. In other words, the toolbar’s functionality depends on some kind of state.

ExtJS Toolbar Extension

Now as far as I know, there isn’t a plugin or user extension available which meets the requirements my application needs. Therefore I created my own!

Override Toolbar Buttons/Actions

The first thing I needed to do was mark which toolbar options need to be hidden in specified states. I did this via a simple override statement on Ext.Component() and Ext.Action(). This was necessary because ExtJS toolbars can contain any Component() sub-class AND Ext.Action() instances which do not inherit from Component(). Thus I needed to cover both cases.

/**
 * Add markAsHidden member to all Components.
 * Used for marking toolbar items/buttons as hidden
 */
Ext.override(Ext.Component, {
    markAsHidden: []
});
Ext.override(Ext.Action, {
    markAsHidden: []
});

The new “markAsHidden” member  is an array (defaults to an empty array) which can be given any number of ’states’ in which the button or action must be hidden from the user.

You can now add these states via the button/action config:

var myButton = new Ext.Action({
    text: 'My Button',
    markAsHidden: [ 'someState', 'anotherState' ],
    handler: function() { ... }
});

Extend Ext.Toolbar()

My.Toolbar() is a basic extension of the Ext.Toolbar() object, with only two things which require explanation.

/**
 * @class My.Toolbar
 * @extends Ext.Toolbar
 * @constructor
 * @param {object} configObj
 * @cfg {array} items
 */
My.Toolbar = function(configObj) {
    var thisObject = this;

    /**
     * @method
     * @description Method to update the toolbar, showing/hiding specified
     *     buttons based on the passed display type.
     *     Common values are: 'root', 'child', 'query'
     * @param {string} displayType
     */
    this.updateDisplay = function(displayType) {
        function checkForHiddenFlag(toolbarItem) {
            if (toolbarItem.markAsHidden.indexOf(displayType) == -1) {
                toolbarItem.show();
            }
            else {
                toolbarItem.hide();
            }

            //cascade into the menu actions
            if (toolbarItem.isXType('button')) {
                if (toolbarItem.menu) {
                    toolbarItem.menu.items.each(checkForHiddenFlag);
                }
            }
        }

        thisObject.items.each(checkForHiddenFlag);
    };

    Ext.apply(this, {
        items: configObj.items
    });

    My.Toolbar.superclass.constructor.apply(this, arguments);

    this.mon(
        thisObject,
        'render',
        function(thisComponent) {
            thisComponent.updateDisplay('root');
        }
    );
};
Ext.extend(My.Toolbar, Ext.Toolbar, {});

First, I added an updateDisplay() method which (when called with a string parameter) will hide any toolbar options marked to-be-hidden in the specified state. It even goes into sub-menus to hide menu options!

Second, I run updateDisplay(‘root’) when the toolbar renders to put the grid into a default state.

So… now what?

The idea is that we can change the state of the toolbar whenever we need to – like on UI events such as tree-node clicks or a combo-box selection.

myTree.on(
    'click',
    function(theNode, theEvent) {
        myGrid.getTopToolbar().updateDisplay('someState');
    }
);

This extension is still a bit of a work in progress, but hopefully it helps a few of you ExtJS developers out there!

Book Review: ExtJS 3.0 Cookbook

Friday, November 20th, 2009

As I mentioned in an earlier post, Packt Publishing contacted me a few weeks ago asking if I wanted to review ExtJS 3.0 Cookbook (written by Jorge Ramon). Since I do a ton of software development using ExtJS, and I like free stuff, I agreed to review the book.

Disclaimer: I am not getting paid for this review, but I did get the book for free. I don’t work for ExtJS or Packt Publishing.

Who this Book is for

ExtJS 3.0 Cookbook is definitely geared towards JavaScript developers who have some basic understanding of and experience with ExtJS 3.0. If you’re brand-new to ExtJS, you may want to wait a few weeks until you’ve spent some time playing with the various components and layouts that ExtJS offers.

As an experienced ExtJS developer, I can say with absolute certainty that I learned some new tricks while reading this book.

Let’s Start with the Bad

ExtJS 3.0 CookbookI want to start by pointing out the things I didn’t like about this ExtJS 3.0 Cookbook. Why? Because you should read this book, and I want you to walk away from this post remembering the things I liked!

Overall, a general complaint I have about the examples is that many of them are similar to those given on the ExtJS website. If I were writing my own book (which I haven’t done…) I would try to come up with more unique examples. Jorge did spend some time doing that – but not enough time for my liking.

Chapter 1 (DOM and Data Types, the ExtJS Way) seemed a bit all-over-the-place. While the examples and explanations were well written, topics like building custom ExtJS extensions are complicated. For developers new to ExtJS, a more in-depth focus will absolutely be necessary. Topics like sniffing the user’s browser or OS aren’t advanced enough to interest seasoned ExtJS developers. Overall, I thought Chapter 1 was a bit of a waste.

Chapter 2 (Laying Out a Rich User Interface) doesn’t mention HBOX and VBOX layouts – two of the most useful layout containers. These layouts were new features in ExtJS 3.0, and I’m disappointed that Jorge didn’t give any explanation of them.

Chapter 6 mentions a drag/drop implementation between two grids (basically the example seen here) – which is a great introduction – but only spends 4 paragraphs explaining the example. Drag-and-drop is one of the most useful (and often confusing) concepts in ExtJS, and I’m disappointed that this example wasn’t expanded. In fact, Jorge probably should have devoted an entire chapter to this example, maybe even adding some extra functionality.

I also thought it was odd that Chapter 7 (Keeping Tabs on your Trees) covered TabPanels and Trees at the same time. Although I often use the two together when building my user interfaces, I think the topics could have been covered separately and each given more attention. Specifically, I don’t have much experience with the ColumnTree extension or drag/drop between TreePanels… I don’t know why they’re in the same chapter as the TabPanel.

Lastly, I don’t know why Jorge added the Ext.Slider() to Chapter 9 (Well-charted Territory). The Slider() isn’t a chart, and he doesn’t add it into an example using a chart. It’s just out-of-place.

Things I Really Liked

Throughout the book, Jorge Ramon shows the reader examples using three distinct headers:

  1. Name of the concept
  2. How to do it…
  3. How it works…

Ramon’s approach to explaining the examples is virtually flawless, and the box-style headers make it easy to follow. I haven’t seen too many coding books use this technique, so kudos to whoever thought of it!

ExtJS 3.0 Cookbook

Chapter 2 (Laying Out a Rich User Interface) has a lot of good stuff. I was particularly impressed when I saw the Portal drag/drop example, although I didn’t really dig deep enough to see if it’s the same example shown on the ExtJS website. In either case, Jorge did a great job explaining how it all works!

Chapter 3 (Load, Validate, and Submit Forms) was more useful to me than I thought it would be. Forms are the basis of web-based applications, and any developer using ExtJS has (more than likely) had to create Ext.form.FormPanel() objects at some point. Awesome tips included: changing the location of validation errors and auto-validation of URLs/email addresses.

Chapter 4 (Fun with Combo Boxes and Date Fields) has a lot of great examples for customizing these two widgets. The best samples in this chapter involve XTemplates and data-paging on the ComboBox, and disabling days/dates in the date picker. I actually didn’t know you could disable days/dates on the date picker widget… I learned something!

Chapter 5 (Using Grid Panels to Display and Edit Tabular Data) didn’t really teach me anything new, but I will say that I was impressed by the number of examples Jorge uses to demonstrate the power of the ExtJS grids. This chapter covers everything from using remote data sets (in both XML and JSON) to inline editing, grouping and expandable rows. If you’re not an expert on ExtJS grids before you read this chapter, you’ll know everything you need to know when you’re finished!

Chapter 6 (More Applications of Grid and List Views) is another great compilation of examples which build on the ExtJS grid. ExtJS GridViews are (in my opinion) one of the best features of the entire framework because they allow the developer to customize the way the UI displays the data. Jorge also covers the RowEditor plugin (new in ExtJS 3.0) and dives into creating grid cell tooltips.

Chapter 8 (Making Progress with Menus and Toolbars) demonstrates a bunch of ways to make your application interactive. While most of the examples won’t blow your mind, I found that they do spark ideas to accomplish any number of things. I particularly liked the customization of the progress bar!

Finally, Chapter 10 (Patterns in ExtJS) contains solid direction for developers looking to build rich internet applications with ExtJS. In all honesty, this chapter could probably be expanded into a separate book… but it serves as a nice conclusion for the previous nine chapters. Jorge builds on many of the examples he mentioned in earlier chapters and gives some final advice for developers to move forward with their own applications.

The Best Chapter

If I had to pick a single reason to buy ExtJS 3.0 Cookbook, it would definitely be Chapter 9 (Well-Charted Territory).

Why?

For starters, the ExtJS website samples don’t do a great job explaining how to use many of the available charts. The online documentation also lacks direction. Jorge is the first person I’ve seen who thoroughly explains how to use each type of chart, and his examples are both unique and helpful. Kudos!

Final Thoughts

I really liked this book!

I’ve read a lot of programming textbooks, and none are nearly as helpful or interesting as ExtJS 3.0 Cookbook. It is a quick read for containing 356 pages, and Jorge Ramon does a fantastic job offering tips and tricks for ExtJS developers.

Regardless of your experience level, the ExtJS 3.0 Cookbook will absolutely teach you something new!