Archive for the ‘All’ Category

Make Table Rows Sortable Using jQuery UI Sortable

Thursday, July 30th, 2009

I wrote an article on the LANIT Development blog about a problem that I ran into when trying to set up a basic sortable table using jQuery UI. The columns would collapse down once the dragging began.

sortable-row-collapsed

This was fixed by adjusting the helper object for the sortable function. Check out the article for all the details, but here is a sample of the code if you are just looking for the solution:

// Return a helper with preserved width of cells
var fixHelper = function(e, ui) {
	ui.children().each(function() {
		$(this).width($(this).width());
	});
	return ui;
};
 
$("#sort tbody").sortable({
	helper: fixHelper
}).disableSelection();

Keep Original Variable State Between Event Binding and Execution

Wednesday, July 15th, 2009

Or: Binding Events Inside of a Loop with jQuery

I wrote an article over on the LANIT Development Blog about saving the state of a variable inside a closure that is not executed immediately. For example, functions passed into event binding or setTimeout(). Here is a quick rundown of the problem and the solution (using the jQuery library).

The Problem

$(function() {
	$("body").append("<ul id='container'></ul>");
 
	for (var i = 0; i < 5; i++)
	{
		var $item = $("<li />").text("Item " + i);
		$("#container").append($item);
 
		$item.click(function() {
			alert("You clicked number " + i);  // always "You clicked number 5"
		});
	}
});

The Solution

$(function() {
	$("body").append("<ul id='container'></ul>");
 
	for (var i = 0; i < 5; i++)
	{
		var $item = $("<li />").text("Item " + i);
		$("#container").append($item);
 
		(function() { // Closure here here instead of "bindItem()"
			var ind = i;
			$item.click(function() {
				alert("You clicked number " + ind); // Works as expected
			});
		})(); // Execute immediately
	}
});

The solution uses an immediately executing function to create a new scope and declare a variable “ind” that is reserved a new space in memory instead of simply referencing “i”. Check out the full article for more details.

jQuery outerHTML Snippet

Tuesday, June 16th, 2009

outerHTML is a property that is provided by Internet Explorer that returns the full HTML of an element (including start and end tags). In jQuery, the html() function returns the innerHTML of an element, which is just the HTML inside the element (not including the start and end tags).

There came a time that I wanted to get the outerHTML of an element, and I found that Brandon Aaron shared a jQuery code snippet that does this exactly. It does the trick for most cases, but there was one problem that I ran into. I wanted to get the outerHTML of an element inside of an iframe, and I got a ‘Permission Denied’ error in Internet Explorer.

The problem was that it was appending an element belonging to the iframes ‘contentDocument’ into an element belonging to the global ‘document’ element.
Using the jQuery(html, ownerDocument) overload of the jQuery core function, this error was fixed:

$.fn.outerHTML = function() {
    var doc = this[0] ? this[0].ownerDocument : document;
    return $('<div>', doc).append(this.eq(0).clone()).html();
};

Extending jQuery to Select ASP Controls

Monday, June 8th, 2009

One thing that has always been annoying about programming JavaScript in an ASP.NET Web Forms environment is that the ID attribute of HTML controls rendered out from ASP controls is unpredictable.

	<asp:TextBox runat="server" ID="txtPhoneNumber" />

renders out as something like:

	<input type="text" id="ctl00_ctl00_ctl00_main_Content_txtPhoneNumber" 
		name="ctl00$ctl00$ctl00$main$Content$txtPhoneNumber" />

I did a write up over on the LANIT development blog about a solution to this problem using jQuery.

Check out the post for more details, but here is the function:

	jQuery.expr[':'].asp = function(elem, i, match) {
		return (elem.id && elem.id.match(match[3] + "$"));
	};
 
	$(":asp(txtPhoneNumber)").keyup(...);

A* Search Algorithm in JavaScript

Wednesday, June 3rd, 2009

View the online demo

I first implemented the A* algorithm for a research group I was in through school (Computer Graphics and Image Understanding). A* is a best-first, graph search algorithm. Some basic information can be found on the Wikipedia page for A* and the external links contained in it. Please refer to that page for general reference about the algorithm, I will simply explain in my own words how it works and how I got it working.

A* algorithm in JavaScript

A* algorithm in JavaScript

Why JavaScript?

Because it was easy to deploy!

Since I know JavaScript pretty well, and most of the examples you can find are in C, Java or a similar language that you cannot run without downloading source code or executables, I thought it would be a good idea to program it on an html page. This way, people could see what was going on and view the source very easily (download Firebug and give it a try if you don’t already have it).

My hope was to build a page that could be extended with other search algorithms by separating the UI code (that generates a graph with walls and animates the path that is determined by an algorithm), and the algorithm that finds the path. Maybe I will get around to plugging in some more algorithms sometime and making it into a little resource for graph search algorithms.

How?

search.html

Just a basic html file that includes jQuery, the excellent JavaScript library, main.css, graph.js, and astar.js. Also, I have a JavaScript block that initializes the page.

graph.js

The point of this file is to build the graph, call the search function, and animate the results after the search has returned. It also has an option to show the debugging information created by the search algorithm. I won’t get too into the code here, since it distracts from the search algorithm.

Please take a look at it, be aware that there are some improvements I would make if I was to rewrite this today. First, I would like to convert it to a jQuery plugin. Also, it modifies the Array.prototype to add on specific methods (findGraphNode and removeGraphNode) for search algorithms, which may not be ideal for bigger projects. For this little page, I’m not too worried about it, but if I do get around to adding in more algorithms, I will probably improve this code.

astar.js

This is the actual implementation of the algorithm. I will do my best to explain what is going on, but feel free to just look at the source of the example, or just download astar.js.

There are three functions that we keep track of for nodes that we look at:

  • g(x): The total cost of getting to that node (pretty straightforward). If we reach a node for the first time or reach a node in less time than it currently took, then update the g(x) to the cost to reach this node.
  • h(x): The estimated time to reach the finish from the current node. This is also called a heuristic. We online need to update this if it is not set already, since the distance to the finish will not change even if the path we took to arrive at a node changes. Note: There are many different ways to guess how far you are from the end, I use the Manhattan distance in this implementation.
  • f(x): Simply g(x) + h(x). The lower the f(x), the better. Think about it like this: the best node is one that takes the least total amount of time to arrive at and to get to the end. So, a node that took only 1 step to arrive at and 5 to get to the end is more ideal than one that took 10 to arrive and and only 1 to get to the end.

Here is some high level pseudocode of what is happening in the algorithm. Also see the Wikipedia pseudocode for another example.

  push startNode onto openList
  while(openList is not empty) {
     currentNode = find lowest f in openList
     if currentNode is final, return the successful path
     push currentNode onto closedList and remove from openList
     foreach neighbor of currentNode {
         if neighbor is not in openList {
                save g, h, and f then save the current parent
                add neighbor to openList
         }
         if neighbor is in openList but the current g is better than previous g {
                 save g and f, then save the current parent
         }
     }

Here is the JavaScript:

 
var astar = {
	init: function(grid) {
		for(var x = 0; x < grid.length; x++) {
			for(var y = 0; y < grid[x].length; y++) {
				grid[x][y].f = 0;
				grid[x][y].g = 0;
				grid[x][y].h = 0;
				grid[x][y].debug = "";
				grid[x][y].parent = null;
			}	
		}
	},
	search: function(grid, start, end) {
		astar.init(grid);
 
		var openList   = [];
		var closedList = [];
		openList.push(start);
 
		while(openList.length > 0) {
 
			// Grab the lowest f(x) to process next
			var lowInd = 0;
			for(var i=0; i<openList.length; i++) {
				if(openList[i].f < openList[lowInd].f) { lowInd = i; }
			}
			var currentNode = openList[lowInd];
 
			// End case -- result has been found, return the traced path
			if(currentNode.pos == end.pos) {
				var curr = currentNode;
				var ret = [];
				while(curr.parent) {
					ret.push(curr);
					curr = curr.parent;
				}
				return ret.reverse();
			}
 
			// Normal case -- move currentNode from open to closed, process each of its neighbors
			openList.removeGraphNode(currentNode);
			closedList.push(currentNode);
			var neighbors = astar.neighbors(grid, currentNode);
 
			for(var i=0; i<neighbors.length;i++) {
				var neighbor = neighbors[i];
				if(closedList.findGraphNode(neighbor) || neighbor.isWall()) {
					// not a valid node to process, skip to next neighbor
					continue;
				}
 
				// g score is the shortest distance from start to current node, we need to check if
				//	 the path we have arrived at this neighbor is the shortest one we have seen yet
				var gScore = currentNode.g + 1; // 1 is the distance from a node to it's neighbor
				var gScoreIsBest = false;
 
 
				if(!openList.findGraphNode(neighbor)) {
					// This the the first time we have arrived at this node, it must be the best
					// Also, we need to take the h (heuristic) score since we haven't done so yet
 
					gScoreIsBest = true;
					neighbor.h = astar.heuristic(neighbor.pos, end.pos);
					openList.push(neighbor);
				}
				else if(gScore < neighbor.g) {
					// We have already seen the node, but last time it had a worse g (distance from start)
					gScoreIsBest = true;
				}
 
				if(gScoreIsBest) {
					// Found an optimal (so far) path to this node.	 Store info on how we got here and
					//	just how good it really is...
					neighbor.parent = currentNode;
					neighbor.g = gScore;
					neighbor.f = neighbor.g + neighbor.h;
					neighbor.debug = "F: " + neighbor.f + "<br />G: " + neighbor.g + "<br />H: " + neighbor.h;
				}
			}
		}
 
		// No result was found -- empty array signifies failure to find path
		return [];
	},
	heuristic: function(pos0, pos1) {
		// This is the Manhattan distance
		var d1 = Math.abs (pos1.x - pos0.x);
		var d2 = Math.abs (pos1.y - pos0.y);
		return d1 + d2;
	},
	neighbors: function(grid, node) {
		var ret = [];
		var x = node.pos.x;
		var y = node.pos.y;
 
		if(grid[x-1] && grid[x-1][y]) {
			ret.push(grid[x-1][y]);
		}
		if(grid[x+1] && grid[x+1][y]) {
			ret.push(grid[x+1][y]);
		}
		if(grid[x][y-1] && grid[x][y-1]) {
			ret.push(grid[x][y-1]);
		}
		if(grid[x][y+1] && grid[x][y+1]) {
			ret.push(grid[x][y+1]);
		}
		return ret;
	}
};

Conclusion

This A* search implementation could be used as a component to larger system (like a game – maybe tower defense or puzzle), or just for learning purposes. I have done my best to make the code understandable and to present the concepts in a way that would help someone who has never seen the algorithm before, or someone who is not very familiar with JavaScript. Hopefully, if you don’t know JavaScript, you will at some point take the time to learn it. It is a very useful language with a huge deployment platform (the Internet).

Feel free to view the demo, or download graph.js, astar.js, and search.css to mess around with it.

Book Review: Mother Night

Wednesday, May 13th, 2009
We are what we pretend to be, so we must be careful about what we pretend to be.

Mother Night

Kurt Vonnegut’s Mother Night is narrated by a fictional character, Howard W. Campbell Jr. Campbell is an American playwright who was living in Germany during World War II and became a well known Nazi propagandist and war criminal.

Campbell had accepted the task of being an American spy at the beginning of the war. He transmitted messages through deliberate pauses, coughing, etc. in his radio transmissions. Throughout the war, he was the most reliable agent of his kind that America had and survived the war undetected.

Living a secretive and quiet life in New York City after the war, Campbell’s identity is suddenly exposed. The novel is a memoir that he is writing from inside an Israeli prison awaiting trial for his war crimes.

Campbell seems to be both good and evil at the same time. But is he essentially good or essentially evil?

In an internal sense, his actions were good – the information he was passing through the airwaves was helpful to the Allies and it took a total sacrifice of his reputation and his life to provide this service. His career as an author and playwright was gone, he lost his wife, he would never be accepted as a member of society in his home country and he continued to do his work in spite of these things.

However, the external Campbell, the person that the world saw, was clearly evil. When his father-in-law, who would have “been delighted” to figure out that Campbell had been a spy, was speaking with him near the end of the war he says:

You could have never served the enemy as well as you served us, … I realized that almost all the ideas that I hold now, that make me unashamed of anything I may have felt or done as a Nazi, came not from Hitler, not from Goebbels, not from Himmler–but from you… You alone kept me from concluding that Germany had gone insane.

When judging the morality of Campbell, which of these people matter, the inner or outer person?

This is perhaps the main question posed by the book. Which person is you? Vonnegut explicitly states the moral of the story at the beginning: “We are what we pretend to be, so we must be careful about what we pretend to be.” You are the sum of all of your parts. The actions that you take as a means to accomplish something are as much a part of you as the something that is accomplished in the end. No matter the circumstances in which you find yourself, you still have to live with the actions that you take.

Campbell seems surprised by this concept when visited by his “Blue Fairy Godmother” (the man who recruited him as an American spy) long after the war. They are speaking about how only 3 people in the world knew that Campbell was a spy.

“Three people in the world knew me for what I was–” I said. “And all the rest–” I shrugged. “They knew you for what you were, too,” he said abruptly. “That wasn’t me,” I said, startled by his sharpness. “Whoever it was… he was one of the most vicious sons of bitches who ever lived.”

No matter what his intentions, Campbell was a Nazi.

Campbell is a fitting main character to portray this moral. He is not quite a hero and not quite an antihero. He is a lucid protagonist who is neither ignorant nor insane. He knew what he was doing at all times and he realized that the orders he took were either ignorant or insane, and he did them anyway. He is a reminder that even in difficult times, we need to take our actions for what they are, and not what we hope they will be.

Multipart Form Post in C#

Friday, May 8th, 2009

I recently had to access a web API through C Sharp that required a file upload. This is pretty easy if you have an HTML page with a form tag and you want a user to directly upload the file.

<form method="POST" action="http://localhost/" enctype="multipart/form-data">
	File : <input type="file" name="content" size="38" /><br />
	<input type="hidden" name="id" value='fileUpload' />
 </form>

However, this is not always a reasonable path to take. Sometimes you may be wanting to access a file that is already in a system and you don’t want a new upload. If you are accessing an external API, this is probably always the case. Unfortunately, building this post using C# is not quite as straightforward. I first tried using the WebClient UploadFile method, but it didn’t fit my needs because I wanted to upload form values (id, filename, other API specific parameters) in addition to just a file.

So, I needed to roll my own form post. Here is the Multipart Form RFC and the W3C Specification for multipart/form data. After reading these links and searching some forums, here is what I came up with.

Note: If anyone is interested in this code in Visual Basic, reader Mike Ferreira converted the code into VB.Net in a comment below.

public static class FormUpload
{
	private static readonly Encoding encoding = Encoding.UTF8;
	public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)
	{
		string formDataBoundary = "-----------------------------28947758029299";
		string contentType = "multipart/form-data; boundary=" + formDataBoundary;
 
		byte[] formData = GetMultipartFormData(postParameters, formDataBoundary);
 
		return PostForm(postUrl, userAgent, contentType, formData);
	}
	private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
	{
		HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest;
 
		if (request == null)
		{
			throw new NullReferenceException("request is not a http request");
		}
 
		// Set up the request properties
		request.Method = "POST";
		request.ContentType = contentType;
		request.UserAgent = userAgent;
		request.CookieContainer = new CookieContainer();
		request.ContentLength = formData.Length;  // We need to count how many bytes we're sending. 
 
		using (Stream requestStream = request.GetRequestStream())
		{
			// Push it out there
			requestStream.Write(formData, 0, formData.Length);
			requestStream.Close();
		}
 
		return request.GetResponse() as HttpWebResponse;
	}
 
	private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
	{
		Stream formDataStream = new System.IO.MemoryStream();
 
		foreach (var param in postParameters)
		{
			if (param.Value is FileParameter)
			{
				FileParameter fileToUpload = (FileParameter)param.Value;
 
				// Add just the first part of this param, since we will write the file data directly to the Stream
				string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n", 
					boundary, 
					param.Key, 
					fileToUpload.FileName ?? param.Key, 
					fileToUpload.ContentType ?? "application/octet-stream");
 
				formDataStream.Write(encoding.GetBytes(header), 0, header.Length);
 
				// Write the file data directly to the Stream, rather than serializing it to a string.
				formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length);
			}
			else
			{
				string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}\r\n", 
					boundary, 
					param.Key, 
					param.Value);
				formDataStream.Write(encoding.GetBytes(postData), 0, postData.Length);
			}
		}
 
		// Add the end of the request
		string footer = "\r\n--" + boundary + "--\r\n";
		formDataStream.Write(encoding.GetBytes(footer), 0, footer.Length);
 
		// Dump the Stream into a byte[]
		formDataStream.Position = 0;
		byte[] formData = new byte[formDataStream.Length];
		formDataStream.Read(formData, 0, formData.Length);
		formDataStream.Close();
 
		return formData;
	}
 
	public class FileParameter
	{
		public byte[] File { get; set; }
		public string FileName { get; set; }
		public string ContentType { get; set; }
		public FileParameter(byte[] file) : this(file, null) { }
		public FileParameter(byte[] file, string filename) : this(file, filename, null) { }
		public FileParameter(byte[] file, string filename, string contenttype) 
		{
			File = file;
			FileName = filename;
			ContentType = contenttype;
		}
	}
}

Here is the code to call the MultipartFormDataPost function with multiple parameters, including a file.

 
// Read file data
FileStream fs = new FileStream("c:\\people.doc", FileMode.Open, FileAccess.Read);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, data.Length);
fs.Close();
 
// Generate post objects
Dictionary<string, object> postParameters = new Dictionary<string, object>();
postParameters.Add("filename", "People.doc");
postParameters.Add("fileformat", "doc");
postParameters.Add("file", new FormUpload.FileParameter(data, "People.doc", "application/msword"));
 
// Create request and receive response
string postURL = "http://localhost";
string userAgent = "Someone";
HttpWebResponse webResponse = FormUpload.MultipartFormDataPost(postURL, userAgent, postParameters);
 
// Process response
StreamReader responseReader = new StreamReader(webResponse.GetResponseStream());
string fullResponse = responseReader.ReadToEnd();
webResponse.Close();
Response.Write(fullResponse);

Hopefully this code can help someone, figuring out exactly where to place the boundary and newlines in between form key-value pairs caused a little bit of grief during development. This is some functionality that would be really nice inside of the language library, but it seems like in most languages this is something you end up coding yourself.

C# Tips – Null Coalescing ??

Tuesday, May 5th, 2009

I have always enjoyed using the logical OR operator in JavaScript (||) as an oppurtunity to check for a null-like value, specifically to provide default parameters for functions or to check for existence of a property on a collection. I think they are a great way to make code more concise, and if used well, more readable.

These two functions do the same thing, but the first is shorter and more readable to people who may have to go back and modify it later.

function contentDocument(frame) {
    // If the frame.contentDocument either doesn't exist or is a null 
    // value, it will skip to the next value down the line 
    return frame.contentDocument || 
        frame.contentWindow.document || 
        frame.document;
}
 
function contentDocumentVerbose(frame) {
    // This works, but is possibly too verbose for such a simple task
    if (frame.contentDocument) {
        return frame.contentDocument;
    }
    else if (frame.contentWindow) {
        return frame.contentWindow.document;
    }
    else if (frame.document) {
        return frame.document;
    }
}

I was happy to see that C# has a similar feature, the Null Coalescing Operator.

This is nice for the same reasons, and is more readable than the normal ternary operator when simply checking null. Of course, if I am not checking for a null value, but a more complex boolean expression, I will usually use the ternary operator or an if-else block it is more than just a variable assignment or return statement. Anytime I use any extra syntactical feature, it is my hope to make the code more readable.

Anyway, here is an example of the ‘??’ (coalescing) operator contrasted with the ‘?:’ (ternary) operator.

string APP_DEFAULT = "application/octet-stream";
 
private string GetContentType(string contentType)
{
    // Nice and readable.  The '??' operator can be very useful.
    string FUNCTION_DEFAULT = null;
 
    return contentType ?? FUNCTION_DEFAULT ?? APP_DEFAULT;
}
 
private string GetContentTypeTernary(string contentType) 
{
    // This is NOT readable.  Please do not use nested ternary
    // operators... They take too much energy to figure out.
    string FUNCTION_DEFAULT = "text/plain";
 
    return (contentType != null) ? contentType :
        ((FUNCTION_DEFAULT != null) ? FUNCTION_DEFAULT : APP_DEFAULT);
}

Newsflash Is Live

Wednesday, April 29th, 2009

Newsflash App Store

Newsflash is released into the App Store as of April 27th.  It has made it onto the top 25 free news apps, and got about 500 downloads in the first day.  Definitely not a huge release by App Store standards, but it is still exciting to see all of the use!

We are looking forward to getting some feedback and releasing a version with some upgrades. One improvement would be to have international geocoding. Right now, we rolled our own geocoding database from Geocoder.us (which only works in the United States), but Google just released an API for reverse geocoding that may work better. I will be keeping an eye on the reviews to see what people like and don’t like about this first version.

Check out the Newsflash website for more info.

Newsflash

Sunday, April 5th, 2009

I recently completed a contest through the University of Missouri – Columbia.  The goal was to make an iPhone application that was somehow journalism or advertising related.

As a group we decided that there was no real good news reader for the iPhone. Sure, there are some RSS readers, but you need to subscribe to all the feeds yourself. Also, there are a few good apps for certain news sources (New York Times, AP Mobile News). We wanted to make a news aggregator for the iPhone. Using existing APIs to get the articles, it turned out to be a reasonable goal and we were able to focus on ease of use and customization. The result was Newsflash, an application with no real business plan.

One of the buildings on Infinite Loop

One of the buildings on Infinite Loop

One of the coolest parts of the contest was that the finalists got to visit Apple’s campus in Cupertino, CA.  We went to an executive briefing center and got to show off our work to some of the engineers working on the iPhone OS.  It was an awesome experience.

Another perk of the contest was getting to learn the iPhone SDK without needing to buy an iPhone (they were provided by the school for the duration of the contest). Hopefully I can get around to using this knowledge to build another app someday.

We put together a low budget video to promote our entry on the school’s website.  Newsflash is totally free and has no advertisements.  It should be in the App Store very soon (pending approval from Apple).  Go ahead and download it… it should at least be worth what you paid for it!