Archive for the ‘AJAX’ Category

Update to Ext.ux.UnitTest()

Monday, August 31st, 2009

Back in May, I started a pet-project on Unit Testing with ExtJS. I just uploaded the newest changes to my Ext.ux.UnitTest() class, and a demo is available here.

The most recent enhancements include:

  • migration from Ext 2.2.1 to Ext 3.0
  • use of Ext.chart.PieChart() to visually track the tests
  • addition of assertTrue() and assertFalse() test methods
  • test grouping, and color-coded group labels

Take a look and let me know your thoughts!

ExtJS 3.0 Themes

Thursday, August 27th, 2009

One of the best improvements offered in ExtJS 3.0 over previous versions is the new CSS structure. JC Bize (an ExtJS Development Team member) had an excellent presentation at the 2009 Ext Conference discussing what had changed and offered some tips on how to build your own themes. I recently migrated my application from 2.x to 3.0, and I’d like to share my experience with creating a new theme.

In 3.0, the CSS data is divided into two logical groups: structural and visual. This makes creating custom themes much easier than it had been in 2.x, as the developer (in most cases) isn’t interested in changing structural CSS definitions. By isolating the visual CSS, developers can play with colors, fonts, and other presentational elements without worrying about breaking their application.

ExtJS 3.0 CSS Theme Structure

The only problem with the improvement is that it left many of the cool 2.x templates behind. New CSS rules prevent some things from rendering correctly – though which “things” depends entirely on which template you might have been using.

Searching the ExtJS message boards, you’ll notice a handful of 3.0 templates – but not an overwhelming number. To save you some time, I compiled a small list:

Of course, the standard “blue” theme comes with 3.0 as a default.

I had been using the Slickness Theme for my application, and I was dreading the thought of having to give it up as I migrated to 3.0. Much to my surprise, the Slickness theme (built for 2.x) works almost perfectly in 3.0! I had to make a few minor CSS adjustments (available here), but here’s what my customized Slickness theme looks like:

Custom ExtJS 3.0 Theme

If you’d like to try out my customized Slickness theme, simply include the “xtheme-slickness.css” file (as you would for any theme), but also include my “xtheme-symphony.css” file AFTER the Slickness CSS file. This way, my CSS styles override the necessary parts of the Slickness theme.

I also attempted to create my own custom theme for ExtJS 3.0 – though I’ll admit it didn’t look nearly as good as the Slickness theme. I basically fake my way through Photoshop, so editing the CSS sprites was a pain in the ass for me. All things considered though, I had a fully customized theme in under 4 hours of work. If you’ve never worked with CSS, 4 hours for a fully customized theme is pretty quick. In 2.x, it probably would have taken days.

Anyone want to tackle creating their own theme for ExtJS 3.0? Here’s the basics:

  1. Open your ExtJS 3.0 folder, and go to /resources/css/
  2. Make a copy of “xtheme-blue.css” and name it whatever you’d like. (e.g. “xtheme-mytheme.css”)
  3. Go to the /resources/images/ folder.
  4. Make a copy of the “/default/” folder and name it whatever you’d like. (e.g. “/mytheme/”)
  5. Open your new CSS file.
  6. Find/Replace all references to “../images/default/” with the path to your new images folder. (e.g. “../images/mytheme/”)
  7. Include your new CSS file in the header of your webpage.

At this point, you have a new theme… albeit an exact copy of the standard “blue” theme. Now it’s just a matter of changing colors in your CSS file and Photoshop-ing the images in your new “/mytheme/” folder.

Granted, I’m making this sound easier than it actually is. Photoshop-ing the CSS sprites and background images is still a tedious process – and if you’re not a Photoshop wizard, it can be pretty frustrating. That being said, I’ll leave the rest of the details as an exercise for the reader. . . besides, the whole point of making a custom theme is to do whatever you want with it. My input beyond this step is really irrelevant.

If anyone out there attempts to create their own theme I’d love to hear your thoughts!

Ext.data.JsonStore

Thursday, August 20th, 2009

Call me a nerd, but I do have a favorite ExtJS class: Ext.data.JsonStore(). I like this class for a number of reasons. . . for starters, it saves several lines of code as you don’t have to declare an Ext.data.Store(), Ext.data.HttpProxy() and Ext.data.JsonReader() class just to read data from the server. Ext.data.JsonStore() does all of that for you, making your code cleaner. . . and who doesn’t like clean code?

I recently found one more reason to love this class. If you return a JSON response from the server which contains a “metaData” property (in addition to whatever “root” property mapped to the actual data), you can save yourself even more lines of code!

For example, a traditional JsonStore() declaration and the JSON response it reads:

Ext.data.JsonStore()

JSON response

As you can see, I have declared a variety of config options for my JsonStore() object. The “baseParams” are sent to the “url” specified. The server response should contain a root attribute (in this case “rootAttribute”), and I’ve told the store to look for the fields “id” and “text” within the returned data.

While this is an improvement over declaring a standard Ext.data.Store() with the HttpProxy() and JsonReader() classes, we can further reduce the number of JavaScript lines required to read the data. Assuming you have thousands of lines of code where you utilize many JsonStore() objects, saving 3 or 4 lines of code per object instance results in maybe 100 lines of code saved or more throughout a large application. Furthermore, it allows the JsonStore() class to become much more flexible.

To accomplish this, we’ll add about 3 lines of code to our server-side file (plus or minus any additional logic needed) which returns the JSON data.

Obviously the “root”, “sortInfo” and “fields” attributes of our original config object are necessary. How else would the JsonStore() class know how to read the returned data? By moving this information into another attribute of the returned JSON object, we can dynamically instruct the JsonStore() class to look for the data we want.

If you read the documentation for the Ext.data.JsonReader() class, you’ll find a section near the top discussing the “metaData” attribute. In essence, the data contained within the “metaData” attribute tell the JsonStore() class what to do with the data it just received. In our case, we’ll tell it which attribute is considered the “root” (to which the actual JSON data is mapped), how to sort the data (via “sortInfo”), and which data fields we want to use (via the “fields” array). All of this is configured on the server – meaning that it’s less code to maintain on the client side.

Take a look at the resulting JsonStore() declaration and the JSON data it accepts:

Ext.data.JsonStore()

JSON response

It’s much simpler!

This also means that for classes like Ext.grid.GridPanel() (as well as any other classes which take a “store” config option), we can dynamically change how those classes are used. In the case of a Grid(), we can dynamically change the column model. In other cases, we could reuse the same JsonStore() to load data for different purposes at different times, saving client-side memory and speeding-up the initial page load. I imagine there are a ton of other uses as well.

While a few of the more advanced users of ExtJS might laugh at the fact I’ve just started playing with this, I find it to be immensely helpful! So helpful, in fact, that I wonder why Ext developers aren’t encouraged to make use of it more often. In any case, have fun with this!

ExtJS: Migrating from 2.2.1 to 3.0

Wednesday, August 19th, 2009

I sat down this morning with the intention of migrating my application from ExtJS 2.2.1 to ExtJS 3.0. Although I’ve been playing with version 3.0 for some time, I was a bit worried that my application (containing more than 20,000 lines of code and many custom objects/extensions) would all but explode. Granted, ExtJS 3.0 didn’t change so dramatically from 2.0 – but with so much custom code I simply wasn’t looking forward to today.

Also, due to the massive CSS changes in 3.0, I have to create a brand new skin to match the “Slickness” we had been using. That’s a task unto itself and I won’t worry about that for now. Expect a follow-up post on that subject.

After importing the 3.0 source code, I logged into my application. I was happy to find that all but one screen rendered and functioned normally (minus one annoying “targetNode is  undefined” error). Fantastic! The only page that didn’t render hit an error on one of my Ext.Toolbar objects, giving me a “toolbar.items.itemAt(0).items is undefined” error. ExtJS did change the way Toolbars and Menus behave slightly in 3.0, so I wasn’t surprised to find an issue like this. A quick edit to that one line of code fixed the problem.

. . .and that was it. I’m utterly floored by how nothing broke.Kudos to you ExtJS!

Next up will be going through each custom over-ride and user extension (UX) to see if they’re still necessary.

Last but not least will be a new skin. Seeing how there’s a lack of 3.0 skins (aka “themes”) available on the message boards I’ll probably offer mine to the community when complete. Hopefully that will be done by the end of next week.

Professional Courtesy

Friday, August 14th, 2009

A few months ago, I wrote a blog post titled Parsing XML: jQuery vs ExtJS. If you don’t feel like reading it, the point of that post is that I was (still am) frustrated by the fact that ExtJS doesn’t have a generic utility that can find a block of HTML/XML in a document that isn’t valid XHTML. For better or for worse, jQuery does allow you to do that.

A reader (identified as “extidiot”) responded saying that the solution was easy and suggested I try his solution. His solution didn’t work because my response object wasn’t a valid HTML/XML/DOM object. I responded saying something like “thanks for your help but it doesn’t work”.

Long story short, I decided to use a regular expression to find the block I needed. Problem solved. End of story.

So I thought.

Apparently, “extidiot” is a member of the ExtJS support team. He must have found my post to have a valid point because he started a thread in the “Feature Requests” forum of the ExtJS message board that very same day. That’s great!

Well, no. I take that back -it’s not great. In a follow up post to his own thread, “extidiot” claims “jQuery apparently does lots of handholding for people who don’t know the difference between textual HTML and a DOM document. The concept being that jQuery can “find” stuff from “HTML” (and the user doesn’t either know or care if the “HTML” is textual HTML, or a DOM document)“. Reading that post, I am a bit irritated for several reasons.

First, I’m taking the “extidiot” name as a direct insult. I met many of the ExtJS support team members at the conference this past April, though not that particular gentleman. The support team was very nice, respectful and seemed to enjoy questions from the public. “extidiot” has a reputation for being “direct” on the message boards, but I feel he’s just being rude. He could at least use his own name when trying to make fun of me on my blog.

Second, I have a valid point. Although I didn’t write those original lines of jQuery, I disagree that it should be considered “handholding”. In fact, being able to parse HTML/XML code from a generic (or invalid) text document is a very helpful utility. If your opinion is that this utility doesn’t fit with the mission of ExtJS – that’s fine. But again, there’s no need to take a personal shot at me.

What irritates me the most is that I actually have a lot of respect for the ExtJS support team – this member included. I don’t care if he doesn’t like or respect me, but it’s really unprofessional to respond like that.