subCHILD

Archive for the JavaScript category

iStockutils.com – Built with Flask and Now Live

I recently set out to learn Python, specifically on the Flask (+Werkzeug/Jinja2) microframework, and did so through developing a tool for iStocphoto.com contributors. The result is iStockutils.com, and the code is available for viewing/forking on GitHub.

I still have much more to learn, but though this exercise I’ve become a big fan of Python and, after working with lots of different templating engines over the years, really like the format and flexibility of Jinja2. Kudos to Armin Ronacher for his fantastic work on all of this.

No kudos though to the iStockphoto folks who haven’t even responded to my request for access to their API. This means that all of the data is currently scraped from the HTML. Nasty.

developerWorks Tutorial: Processing XML with jQuery

posted by admin in Code, JavaScript, jQuery, jQuery, PHP, XML

My tutorial on processing XML with jQuery in the browser is now live on IBM’s developerWorks website. Check it out at:

http://www.ibm.com/developerworks/xml/tutorials/x-processxmljquerytut/index.html

Most JavaScript and jQuery ninjas needn’t read past the title for the gist, but hopefully there’s something new for everyone. Either way, your comments are welcome.

Live XML Editor: Version 1.5

posted by admin in JavaScript, jQuery, PHP, XML
liveXmlEdit_screenshot

I recently had a chance to make a few updates to the Live XML Editor and address some user requests. Version 1.5 is now done and out.  Among the updates are:

- jQuery 1.4 support. Since the editor relies heavily on DOM rendering and events, this update makes the app snappier.

- Comment node display and editing. This was requested by a user and I was surprised that I hadn’t thought of it. Creating comments isn’t supported yet, but its on the to-do list.

- Various bug fixes, tweaks and optimizations.

- Added (MIT) license.

Check it out: http://www.subchild.com/liveXmlEdit.  Code is also on GitHub: http://github.com/subchild/liveXmlEdit/

Make an object loggable()

posted by admin in JavaScript

loggable() is a simple little function for safely making a JavaScript object (console) loggable. (Name was inspired by @furf‘s jquery.bindable.js.)

/**
 * Loggable adds a log method to the passed object.
 * @param obj       {Object}  Object which will get a new log() method
 * @param objName   {String}  Optional parameter for displaying a string before each log output
 * @param debugMode {boolean} Optional switch for disabling logging
 */
function loggable(obj /* , objName, debugMode */){
	var objName   = arguments[1] || "",
		debugMode = (typeof arguments[2]!=="undefined") ? arguments[2] : true,
		prefix    = objName ? objName + ": " : "";
	obj.log = (function(prefix){
		return function(){
			if (debugMode && typeof console!=="undefined"){
				if (arguments.length){
					arguments[0] = prefix + arguments[0];
				}
				console.log.apply(null, arguments);
			}
		}
	})(prefix);
	return obj;
};

So if you have an object like:

var obj = {
  name     : "Alex",
  getName : function(){ return "Alex" },
  setName : function(name){
    obj.name = name;
    obj.log("name was set to", name);
  }
}

loggable(obj, "Obj");

Then, executing:

obj.setName("Balthazar");

Will log this in your console (Firebug or otherwise):

Obj: name was set to Balthazar.

Here it is on GitHub: http://gist.github.com/547926

Slideshowify: Ken Burns Slideshow Effect as a jQuery Plugin

Slideshowify is a jQuery plugin for creating a slideshow of images that will fill the screen with a (cropped) image, then pan across to reveal the rest of it. This is commonly referred to as the Ken Burns Effect and is often seen in documentaries. A nice version is of it can be seen in that Mac screensaver.

Anyhow, here’s a stab at such a thing. Some future enhancements are obvious (pan direction, zooming, transition options, etc.) and anticipate finding the time to add that stuff shortly.

For now, check out the code on github.com and see a demo at www.subchild.com/slideshowify

To use it, include jQuery, jquery.slideshowify.js, then feed slideshowify a selector that matches some images. For example:

$("img").slideshowify();

Alternatively, you could load data from an external feed and call $.slideshowify() with configuration options:

$.slideshowify({
 	dataUrl   : "http://www.gallerama.com/services/gallery/get.php?gid=2107&versions[]=9",
	dataType  : "jsonp",
	randomize : true,
 	filterFn  : function(imgs){
 		var fixedImgs = [];
 		$.each(imgs, function(i, img){
 			fixedImgs.push(img.versions["9"]);
 		});
 		return fixedImgs;
 	},
	afterFadeIn : function(imgData){},
	beforeFadeOut : function(imgData){}
 });

Most of the params here are passed directly to jQuery’s $.ajax() method. Some are used to reformat the data (slideshowify() expects an array of objects of this format: {src:”domain.com/path/to/image.jpg”, w:”600″, h:”400″}), others are hooks or speed (fade, delay) options.

Proper documentation will be provided. Most likely.

Sorting a JSON Array by Property

posted by admin in Code, JavaScript

Sorting arrays of JSON objects is a task that I occasionally come across. Here’s a little utility I’ve been using for a while that does the trick.

/**
 * Sorts an array of json objects by some common property, or sub-property.
 * @param {array} objArray
 * @param {array|string} prop Dot-delimited string or array of (sub)properties
 */
function sortJsonArrayByProp(objArray, prop){
	if (arguments.length<2){
		throw new Error("sortJsonArrayByProp requires 2 arguments");
	}
	if (objArray &amp;&amp; objArray.constructor===Array){
		var propPath = (prop.constructor===Array) ? prop : prop.split(".");
		objArray.sort(function(a,b){
			for (var p in propPath){
				if (a[propPath[p]] &amp;&amp; b[propPath[p]]){
					a = a[propPath[p]];
					b = b[propPath[p]];
				}
			}
			// convert numeric strings to integers
			a = a.match(/^\d+$/) ? +a : a;
			b = b.match(/^\d+$/) ? +b : b;
			return ( (a < b) ? -1 : ((a > b) ? 1 : 0) );
		});
	}
}

Here’s a simple example:

var arr = [
	{name:"Zack", friends:{count:50}},
	{name:"Alex", friends:{count:80}},
	{name:"Mike", friends:{count:30}}
];
sortJsonArrayByProp(arr, "name");
sortJsonArrayByProp(arr, "friends.count");
sortJsonArrayByProp(arr, ["friends","count"]);

[Update] This function now converts strings made up entirely of digits into integers for (presumably) more accurate comparisons, and therefore, sorting.

SWFUpload Doesn't Work with Windows 7

posted by admin in Flash, JavaScript

Uploading files using a browser has never been ideal, partly since JavaScript and/or HTML do not have the privilege to read size of files on the local file system which stands in the way of calculating upload progress and informing the user with a standard progress bar. To get around this, you can use a Java applet, one of the many hacks which involve Perl, PHP/CLI, or the awesome and very customizable SWFUpload. However, as a new Windows 7 user, I discovered that SWFUpload immediately reports 100% completion and the progress reporting fails. I’m guessing the problem is related to Windows 7′s restrictive nature and a new restrictions on flash plugin’s access to the file system, but hopefully the problem is solvable.

In the meantime, its assuring that the uploads using SWFUpload do work, only the reporting part doesn’t, but that’s the whole reason for using it. The problem was reported on the SWFUpload forum and hopefully its being looked into.

Live XML Editor

posted by admin in JavaScript, jQuery, PHP, XML

While I don’t recommend editing XML files by hand, its not an uncommon task and I occasionally find myself having to do it.  As I am a big advocate of web based applications, I was hoping to find a web based XML editor but had trouble finding one.  So I built one.

From the technical point of view, editing the XML directly (rather than translating it to a more edit-friendly format, then converting it back) was something I wanted to explore and jQuery’s fantastic DOM support (which covers XML files as well) seemed to be the right approach.  All of the editing is handled in the browser and each update is reflected in the source XML immediately.  Saving merely consists of pushing the string onto a PHP script which saves the file.

The interface is still a little clunky and could use some visual and functional improvements, but it should get the job done for now.  I’m also planning a number of feature updates.

Let me know how you like.

Go to the Live XML Editor »

jQuery's .live(), Enhanced

posted by admin in JavaScript, jQuery

If you’re not using jQuery’s .live() method you are really missing out. live() works by storing a selector-to-handler mapping in an internal hash which allows it to execute the handler for all existing and future elements which match that selector. This is a fantastic feature, however the current implementation relies on real DOM elements (even if they’re not appended to the document) for access to the selector which slows it down when it really doesn’t need to.

Wouldn’t it be great if it could just store the reference (the “selector”), which would make assigning handlers a constant complexity operation? Its certainly possible, and thanks to Dave Furfero (of blurf.furf.com) you don’t have to wait for a future release of jQuery to use this. (Lets hope they include it.)

Read all about it here:http://blurf.furf.com/2009/09/jquery-live-from-new-york/

Here’s the code:

$.extend({
	live: function(selector, type, fn){
		var jQElem = $(document);
		jQElem.selector = selector;
		jQElem.live(type, fn);
	}
});

Thanks Furf.

How to get (and set) the text value of an XML node in JavaScript using jQuery

posted by admin in JavaScript, jQuery, XML

Edited on October 7th: I realized after the original post that the code provided was not entirely correct.  Specifically, it ignored CDATA values.  Methods below have been updated to reflect that fix.

The logic for extracting the text values is extracted into a separate function:

function getTextNodes(node){
  return $(node).contents().filter(function(){
    return (
      ((this.nodeName=="#text" && this.nodeType=="3") || this.nodeType=="4") // text node, or CDATA node
      && ($.trim(this.nodeValue.replace("\n","")) !== "") // not empty
    );
  });
}

This method first gets the contents of the node (all children, including child nodes, text nodes, comments), and then filters it down to only what it promises to deliver.  It ignores text nodes which contain only blanks, only newlines, or some combination of only those two.

Then, the set/get functions become:

function getNodeValue(node){
   var $textNodes = getTextNodes(node);
       textValue = ($textNodes[0]) ? $.trim($textNodes[0].textContent) : "";
   return textValue;
}

And since we’re at it, here’s a way to set it:

function setNodeValue(node, value){
   var $textNodes = getTextNodes(node);
   if ($textNodes.get(0)) $textNodes.get(0).nodeValue = value;
   else node["textContent"] = value;
}

One other change to note (bolded above, in setNodeValue()) is that if a specific node has no prior text value, instead of setting it using node.textContent, we’re setting it with node["textContent"] since Internet Explorer doesn’t like the first method (property doesn’t exist when blank).  This is good practice since its generally safer.

Recent Posts
Recent Comments
About
aparadekto: Hey, I can't view your site properly within Opera, I actually hope you look into fixi...
wisconsin union theater south pacific: This a really great writeup by you looking forward to come back more very soon....
SumashtDilovf: The genius chained to the official table, should die or go mad, in the same way, as t...
liamecaps: This is very cool. I'd like to try a release as well. Looking for a good web xml edit...
Replica Handbags Sale: I know the title of cheap Replica Handbags Sale are not a source of inspiration, but ...

Subchild is a blog about web development. It's author is Aleksandar Kolundzija, himself a web developer for over 10 years, presently managing the Frontend Engineering team at Meebo. Prior to Meebo, Alex lead the UI Engineering team at MLB Advanced Media, the company behind MLB.com, all official baseball team sites and various other sports and entertainment sites.

When he's not working on websites (such as Gallerama.com) or blogging (here or there, or even there), Alex is playing guitar, producing music, mixing records, taking photos, playing with his kid, or watching documentaries about particle physics, the monetary system, etc.

Let him know what's up: ak @ subchild.com