Converting Ext to jQuery

July 24, 2008

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!