coderholic

Converting Ext to jQuery

I've recently been working on a fairly large javascript project that was using the Ext javascript library. Ext is a powerful javascript library that provides lots of UI widgets, in addition to a DOM manipulation API. The complete Ext library comes in at 546KB, and on this project we were only really using the Ext DOM functions, which made the library a bit overkill. The decision was made to use jQuery instead, which weighs in at only 16KB.

I set about replacing all the existing Ext code with jQuery equivalents. The majority of Ext functions map directly onto jQuery equivalents, which made things easier. For example:

Ext.get('id') -> $('#id')
Ext.get('id').query('.class') -> $('#id .class')

Some things don't map quite so well, but are still relatively simple. The position functions are one such example:

Ext.get('id').getAbsoluteXY() -> [$('#id').offset().left, $('#id').offset().top]
Ext.get('id').bottom() -> $('#id').offset().top + $('#id').height()

However, some Ext functions have no equivalents at all in jQuery. Two Ext functions we were using with no jQuery equivalent were serialiseForm and decodeJson. I came up with the replacement functions below:

$.fn.decodeJson = function(string) {
        // if we don't have a string then there isn't any decoding to be done, return as is
        if(typeof(string) != "string") return string;
        // make sure the string starts with { and ends with }
        if (string.substr(0,1) == "{" && string.substr(string.length - 1,1) == "}") {
            eval("var decoded = " + string);
            return decoded;
        }
        return {};}

$.fn.serialiseForm = function(form) {
        // We might have been passed a form ID, or a form object
        if(typeof(form) == "string") form = jQuery('#' + form);

        // lets try ourselves!
        var getValuesFromForm = function(form) {
            var serialised = [];
            jQuery(form).children().each(function() {
                var child = jQuery(this);

                if (child.children().length > 0) {
                    var t = getValuesFromForm(child);
                    if(t.length > 0) jQuery.merge(serialised, t);
                }

                var name = child.attr('name');
                var type = child.attr('type');
                var val = child.val();

                if(name) {
                    if (type != 'checkbox') {
                        serialised.push(encodeURI(name) + '=' + encodeURI(val));
                    } else {
                        var checked = child.attr('checked');
                        if (checked) {
                            serialised.push(encodeURI(name) + '=' + encodeURI(val));
                        }
                    }
                }
            });

            return serialised;
        }

        var data = getValuesFromForm(form).join("&");
        return data;
}

The only feature of Ext being used without a relatively simple replacement was Ext.basicDialog, a UI widget. The jQuery BlockUI plugin came to the rescue:

dialog.hide() -> $.unblockUI();

During this rewrite I came to appreciate just how powerful jQuery selectors are. The codebase was considerably smaller after the rewrite, due to the expressiveness of jQuery. Many 3 or 4 liners in Ext would condense down to a single expression in jQuery!

Posted on 24 Jul 2008
If you enjoyed reading this post you might want to follow @coderholic on twitter or browse though the full blog archive.