Category Archives: JavaScript


I’ll be the first to admit that my dad did my SAT book’s website (; I did nothing but proofread and offer wordsmithing suggestions. As part of the website design process, my dad and I decided that we should do some “AB” testing of website sales copy, meaning that we would display one of two possible websites to our users at random.

My dad complained to me that most of the existing AB testing solutions were either too difficult to use or were far too complex for the simple act of choosing a page to show to a user. I decided to fix that: I wrote a jQuery plugin called SimpleAB that would switch views in and out. And it only switches views in and out.

The premise is simple: add the class “simpleab-#” (where # is a natural number) to all the elements that you wish to switch in and out with SimpleAB. Elements with the same number will be shown together. That way, you can separate the text and structure of your elements of the page and only AB test the parts you want to.

SimpleAB also has some other nice features:

  • You can choose whether or not to “persist” a view. That is, SimpleAB will set a cookie that will cause the user to always see the same view.
  • You can customize the SimpleAB class name, so that if “simpleab-#” doesn’t float your boat, you can use “mycoolwebsite-#” instead!
  • Even if you persist views, the “flip” feature lets you make sure that all your views look beautiful by iterating through the views as you refresh your SimpleAB page.

Want to see more? SimpleAB is MIT licensed! Check it out on my GitHub:

Quick and Dirty Word Counting in JavaScript

Here’s an interesting problem that came up today during my Gradesolve development: counting the number of words in a particular div. It’s remarkably simple to do so (approximately), efficiently, and correctly. I pass this method the results of a $(“#myelement”).text() call to jQuery:

function wordCount(bodyText){
	var split = bodyText.split(/ |\n|-/);
	var count = 0;
	for (var i = 0; i < split.length; i++){
		if (split[i] != "") count++;
	return count;

This returns a result very close to that returned by LibreOffice. It also runs in O(n) (and Θ(n) and Ω(n)). On my hyperthreading-enabled, 3.6GHz Pentium 4 test PC, it took about 0.76ms to count the words in a 400-word document. That means counting the words in a 100,000-word novel would take 190ms or so (not including any memory allocation time) even on a relatively old machine. In other words, it’s quick!

Saving Massive IE Headaches

It shouldn’t surprise you that I’m still working on Hawgrade–now called “Gradesolve.” I’ve been making a huge amount of progress with it. Well, I suppose I should say “was making a huge amount of progress.” Today was my dreaded IE day: I’ve been testing everything in Internet Explorer.

Most of my time has been spent with the heart of the Gradesolve experience, the “Magic Editor JavaScript Engine (from Hell),” which I have lovingly named magic_editor.js. A surprising amount of the code has worked flawlessly; most of the changes resulted in something that was better in every browser (A big one was updating some jQuery .css() calls to use .offset()). My updates were coming with relative ease (read: I do not enjoy making my code cater to imaginary standards) until I hit a major snafu with the Twitter Bootstrap modal.

The problem was simple: it didn’t work. Not working, however, is easy to fix. The bigger problem was that the modal worked in the Bootstrap documentation. I was at a loss; I spent hours digging through my code, making messy tweaks, and was on the brink of throwing out the comment editing functionality when I finally decided to look at what was going on with the browser standards inside the iframe in which the magic editor does its magic.

I’ll give those of you who’ve had to go through this the doctype of the page that was inside the iframe (generated by an outside source):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

Yep. WHEN I USED IE VERSION 8 OR OLDER, THE DOCUMENT MODE WAS SET TO IE5 QUIRKS. That’s the rough equivalent of trying to run an iOS app on MS-DOS. It’s not going to work.

Luckily, the fix is relatively easy. I added this to the head of my page (it is not feasible to change the doctype of the served page):

<meta http-equiv='X-UA-Compatible' content='IE=edge'>

That forces IE to render in whatever the latest and greatest document mode for the browser mode is.

A Brainf**k Interpreter in JavaScript

Brainf**k (I bet you can guess what the asterisks are covering…) is a tiny, esoteric programming language. It is classified as Turing-complete, but its practical use is very limited (if not nonexistent). BF is an interesting challenge because it is so simple. Many devoted developers spend lots of time creating the smallest, fastest BF interpreters and compilers they can. One user on Codegolf created a BF implementation that was only 106 bytes long. That’s pretty impressive.

BF has eight commands (which will be discussed in a moment). Every program has access to a series of memory blocks that can have any range of values. When a BF program loads, all the “cells” in the memory (really just an array) are initialized in value to zero. BF programs can switch between different blocks of memory (change the array index that they are accessing), increment the values of specific blocks, decrement the values of specific blocks, print a character representation of a block to the screen, or put a character’s value into a block. Programs can also loop. They are executed command-by-command from left to right.

There is no official language specification for BF, so many details are left up to the individual implementation. However, the following standards are pretty common (and were implemented in my BF interpreter):

  • Using bytes for memory. My BF interpreter limits values in cells to [0, 255].
  • Allowing overflows. Blocks overflow when their value goes outside the permissible range of [0, 255]. That is, when a program tries to make a block’s value -1, its value becomes 255, and when a program tries to make a block’s value 256, its value becomes zero.
  • 30,000 blocks (29.3kb) of available memory.
  • Non-command characters are ignored.

The eight commands:

  •  + increases the value of the current block by one.
  • - decreases the value of the current block by one.
  • > increases the block index by one.
  • < decreases the block index by one.
  • . prints the block to the screen as an ASCII character.
  • , gets an ASCII character and puts it in the current block.
  • [ opens a loop. It will jump to the end of the loop if the current block’s value is zero.
  • ] closes a loop. It will jump to the beginning of the loop if the current block’s value is not zero. If it is zero, the program will continue.

I’m not going to teach you how to write BF programs in this post; I’m hardly a maestro of it myself. If you want to learn more about BF, Google is an awesome resource.

My interpreter is pretty simple. The first task was to create a crash-reporting function, since I figured that would probably happen a lot. For future reference, “output” is the ID of the part of the page where BF script output goes.

function crash(reason, at){ // When the program dies
	$("#output").text("CRASHED: " + reason + " ( at char index " + at + ")");

The actual interpreter starts out with the declaration of a run function and all sorts of BF-related variables.

function run(data){ // Runs the BF program. Data: program to run.
	var mem = []; // Program memory
	// Initialize all the memory
	for(var i = 0; i < 30000; i++){
		mem[i] = 0;
	var pointer = 0; // Pointer to memory
	$("#output").text(""); // Clear output field

Next, it loops through each character in the program (specified to the function as data) and if it is BF-legal, the required action is performed. The simple ones (that aren’t loops) are self-explanatory.

for(var i = 0; i < data.length; i++){ 	
        if(data[i] === ">"){ // Right one cell
		if(pointer < 30000) pointer++;
			crash("There are only 30,000 usable cells of memory. Sorry.", i); // Trying to use too many cells.
	else if(data[i] === "<"){ // Left one cell 		
                if (pointer > 0) pointer--;
		else {
			crash("Cannot decrement pointer when pointer is at first cell.", i); // Trying to go below cell zero.
	else if(data[i] === "+"){ // Increment cell value
		if(mem[pointer] > 255) mem[pointer] = 0; // Overflow
	else if(data[i] === "-"){ // Decrement cell value
		if (mem[pointer] > 0) mem[pointer]--;
		else {
			mem[pointer] = 255; // Overflow back to 255
	else if(data[i] == "."){ // Put character to screen
		var memChar = String.fromCharCode(mem[pointer]);
		if (memChar == "\n") memChar = ""; // Turn newlines into breaks
		$("#output").append(String.fromCharCode(mem[pointer])); // Log the correct character from its code
	else if(data[i] == ","){
		mem[pointer] = window.prompt("Please enter one character.").charCodeAt(0); // Set memory to char code

Next come loops. There are loads of elegant ways of going about loops; a stack storing the start indices of loops could be used to avoid all the searching my implementation does. However, simplicity was on my mind when I wrote this program: it suffices to say I took the slow, not-so-elegant way out. When the interpreter encounters the start of a loop (a [), it checks to see if the value of the current cell is zero. If it is not, it just continues along. If it is, things get more interesting. The interpreter loops through the program until it finds the corresponding end of the loop so that the program can continue executing properly.

The task is not as simple as incrementing i (the “instruction pointer,” so to speak) until data[i] is a ]. Other loops could be in the way. The solution is shockingly simple: keep track of the number of newly open loops as the program searches for the end of the original loop. I used a counter to keep track of the loop openings. Every [ increments it; every ] decrements it. When the counter gets to zero and the program finds a ], the index has been found. All that is left is to change the “instruction pointer” to the new location in the program.

The ] routine works in the exact opposite way. It keeps track of ]s instead of [s but is otherwise very similar. Here’s what it looks like:

else if(data[i] == "["){
	if(mem[pointer] != 0) continue;
	else{ // Search for corresponding ]
		var openCount = 0; // # of open loops
		for(var j = i; j < data.length;j++){ // Loop through more characters
			if(data[j] === "[") openCount++; // Another open loop
			else if(data[j] === "]"){ // A closing of a loop
				openCount--; // Decrement open count
				if(openCount === 0){ // If we're at zero, we're done.
					i = j; // Move the program forward
					break; // Stop looping
		if(openCount != 0){
			crash("Open loop.", i);
else if(data[i] === "]"){
	// Same deal as [ except going backwards
	if(mem[pointer] != 0){
		var closeCount = 0; // We use close count on this one because it makes more sense (since we're doing the opposite from before!)
		for(var j = i; j >= 0; j--){
			if(data[j] === "]") closeCount++;
			else if(data[j] === "["){
				if(closeCount === 0){
					i = j;
		if(closeCount != 0) {
			crash("Too many loop closings.", i);

That’s all there is to it. The rest of the page that contains the interpreter, which you can find here, is instructions and a textbox to let you put a program in.

Here’s what the finished product looks like:

It's not as pretty as TextRacer but it gets the job done.

The interpreter running a ROT13 cipher example I found on Wikipedia.

Overall, I was surprised with how quickly I managed to get my interpreter working. I was also glad I went with the architecture I did; though it would have been possible to convert the BF to JavaScript and then eval() it, the program would have lost most of its charm. This program could certainly use some refining but overall, it gets the job done! Happy BFing!

A Fun JavaScript Game I Threw Together

Perhaps you have heard of some keyboarding speed-improving websites such as and TypeRacer, perhaps not. At any rate, my friend David Chen (follow him on Twitter – @Ninchendoz95) has been playing these games a lot, and I was inspired to create something similar. For once, I didn’t go over the top. There’s no glorious database of the most common English language words, no web service that sends the JavaScript behind the game a JSON string full of words to put in, no leaderboard, and minimalist styling on the game web page itself.

You can play my little game here.

I should warn you – there are some issues with TextRacer. It uses the KeyPress event, so words are always somehow one character behind. You can change “keypress” to “keyup” but that introduces another slew of bugs: multiple keys pushed down at once and repeated characters (from holding keys down) registering incorrectly. Luckily, TextRacer more or less works and is amusing to try out a few times.

The code is by no means production-worthy! I was attempting to build something extensible at first but then just started hard-coding the names of divs I was using into the JavaScript.

Here’s TextRacer in action:

TextRacer in action

It almost looks kind of good…

As always, I am amazed by how useful jQuery was in this whole development process. I tested TextRacer in Firefox and Chrome, and the code worked just as well in both.

Have fun tinkering!

Multiple File Upload Made Easy!

Uploading one file to a server is beyond easy with the help of ASP.NET, but when you add more than one file to the mix, things start getting tricky. I ran into multi-upload related issues on a recent in-company project at RMC, and rather than using a plugin, I decided to see if I could come up with something quick-and-dirty with minimal effort.

My project involved migrating a single upload to multiple uploads, so the my first step was to update my server code. Using an HttpFileCollection to retrieve files from a request will work when there is a single .NET file uploader or multiple HTML file input boxes. Here’s how you do it:

HttpFileCollection files = Request.Files;

It’s that easy. The next step is to loop through the uploaded files and save them. You can put the following in a submit button event handler:

HttpFileCollection files = Request.Files;
for(int i = 0; i < files.Count; i++)

The server-sided piece is done. Next comes the client side. For that, we will use jQuery. I realize the way I have gone about doing this isn’t the best jQuery-wise, but it is simple and it works. We will have two helper methods: one to add a file upload box and one to remove it. When we add a file upload box, we just append the relevant HTML to a parent element. When we remove a file element box, we remove the p element from its parent div. Simple enough, right?

    function AddBox(parent){
        // Add HTML for another file upload box to the DOM
        parent.append('<p>input type="file" runat="server" /><a onclick="RemoveBox(this);" href="#">Remove</a></p>');
    function RemoveBox(aContext) {
        // Get jQuery instance of "this" from the link, get its parent element
        // and remove that parent from the DOM.

Note the ‘runat=”server”‘ in AddBox. When I tested this, the files did not show up on the server without the ‘runat=”server”‘ in the input box.

All that is left now is to plug the JavaScript into your ASPX page. You’re good to go with almost no code! The only real issue with this is that if your page has to do a postback to validate, the boxes will not persist (and neither will the selected files) – this could be a big annoyance to your users. The upload will not be asynchronous, either. However, this does the trick if you need a quick, easy solution.

Here’s an example to get you started:

<div id="upload">
    <input type="button" onclick="AddBox($('upload'));" value="Add File Box" />

Unlose Yourself!

In the app I’m working on this summer, I am using GPS functionality pretty extensively. The now-web-standard JavaScript interface is the same as it is in PhoneGap (now Apache Cordova), so I have been able to test on my desktop PC (and you can too). The problem is that your GPS can’t tell you what town you’re in or much more than your latitude and longitude. I needed more than that for my app, so it was jQuery to the rescue.

I apologize in advance for some of my coding practices – writing JavaScript feels a lot like writing Spanish to me, so feel free to alert me of any bad habits I have. Remember what I said in my first post!

Now then, the first thing I did was to write a method to get location XML from PlaceFinder. But how? Yahoo’s documentation has the answer with this example request:,+-77.035974&gflags=R&appid=[yourappidhere]

Easy enough, right? All we have to do is register for an app ID, get our coordinates, build the request, and use AJAX to do the rest of our bidding. We will also have a success callback so the resulting XML can be parsed – you’ll see in a moment.

var lat, long;
var appid = 'YOUR APPID HERE';
function getLocationXML(successCallback) {
    // Get the position
    // Build URL
    // AJAX

Now we have to start coding. To get the current position, just call navigator.getlocation.getCurrentPosition, which can take three possible arguments. We will use the first two, which are the success callback and the failure callback. The success callback takes a position as an argument and the error callback takes the exception as an argument.

function getLocationXML(successCallback) {
    navigator.geolocation.getCurrentPosition(function(position) {
        lat = position.coords.latitude;
        long = position.coords.longitude; // Cordova documentation might be helpful here
        // Build URL
        // AJAX
    function (error) {
        $.error('GPS error (' + error.code + '):' + error.message); // Throw the exception to be handled elsewhere

Right, now we need to build the URL. We will just get string versions of our latitude and longitude and plug them into a variable called URL. This step is simple enough that I feel like I can also cover the AJAX request here. We will use a HTTP GET request (jQuery’s get() method makes this a breeze) to get the data from the Yahoo servers. The AJAX request needs a success callback, for which we will make an anonymous function that calls the successCallback getLocationXML was called with and passes it the data from the AJAX request.

function getLocationXML(successCallback) {
    navigator.geolocation.getCurrentPosition(function(position) {
        lat = position.coords.latitude;
        long = position.coords.longitude; // Cordova documentation might be helpful here
        var url = '' + lat.toString() + ',+' + long.toString()
            + '&amp;gflags=R&amp;appid=' + appid; // Create formatted URL that we can use for AJAX
        // Now we get PlaceFinder data
        $.get(url, function (data) {
            successCallback(data); // call successCallback with what we got from Yahoo
        }, 'xml');
    function (error) {
        $.error('GPS error (' + error.code + '):' + error.message); // Throw the exception to be handled elsewhere

Great, we’re done with the hard part. Now we just have to interpret what Yahoo gives us. First, we will write an XML parser method that takes the XML document Yahoo sends us and retrieve the value of a node:

function xmlParse(xml, node) {
    var d = $(xml); // jQuery version of our XML document
    return d.find(node).text(); // Grab the node text and return.

This may seem overly simplistic to you, but when you look at what Yahoo PlaceFinder sends back (in this case, for 1600 Pennsylvania Avenue), you don’t need anything more complex:

No error
38.898717, -77.035974
1600 Pennsylvania Ave NW
Washington, DC 20006
United States
Pennsylvania Ave NW
District of Columbia
District of Columbia
United States

We’re pretty much done. Here’s some example usage in the head of an HTML document:

$(document).ready(function () {
    var sCallback = function(data) {
        console.log(xmlParse(data, 'city')) // Get information from city node
                                            // In above XML, prints "Washington" in console log.
    getLocationXML(sCallback); // Get the XML and then run the callback when that's done.

That’s it! You can figure out the name of your location with your phone and a little JavaScript. That’s pretty cool.