Javascript

Infinity Pool Doing Well

Posted in Javascript, Projects, Ruby on December 30th, 2009 by Alan Hietala – Be the first to comment

Just a quick update on one of my side projects Infinity Pool. I’ve pulled it out of beta and it is now hosting 300 accounts with over 2500 army lists for the table top game Infinity created. When I started the project I figured it would be a good way to keep my Rails skills up to date I didn’t think it would still have many daily users this far after launch.

As happens with many table top games the rules are about to undergo a huge overhaul. This means much of the codebase will need to change. This will be an interesting challenge as I will need to maintain all of the current users data while adding in all of the new features that are coming due to the new armies and rules.

This should be pretty fun and some good experience. All I can say is I’m grateful I built out a full suite of tests for my code as having them will be essential to ensuring that things don’t break while the site is under heavy reconstruction.

New PlanetEye Features

Posted in Javascript, PlanetEye on April 2nd, 2009 by Alan Hietala – Be the first to comment

We’ve been hard at work at PlanetEye. I’m really excited about the new embedable travelpack maps. The speed that I was able to get this up and running in Google Maps really speaks to the flexibility of their API.

We’ve got out technology working in Google maps now too so we can be entirely map platform independent. Over the next iteration of the map we want to integrate the notes feature from our standard travelpacks to give some descriptive context to each item.

There is a lot of potential for embedable maps especially those that handle grouping of items as elegantly as PlanetEye does.

If you want to get your own map simply create a travelpack and hit the embed button and copy the code into your website or blog.

Writing Mantainable AJAX Javascript

Posted in Javascript on February 11th, 2009 by Alan Hietala – Be the first to comment

Whether you are using the regular xmlhttprequest method or a library like jQuery for ajax, you are going to want to keep those calls as generic as possible. Chances are you’ll end up using them somewhere else in your code. By creating all of your ajax calls generically, you are able to create a concise library that is easily used throughout your site.

Lets look at how this can be achieved. Typically any ajax request no matter what library you use has the connection information, a success handler and a failure handler passed in somehow. Lets look at the following (not so great) code as it demonstrates the bare minimum need to implement an ajax call.

function getDataById(id){
     //spawn the ajax call in library of your choice
     doAjax(connectionInfo,getDataByIdSuccess,getDataByIdFailure);
}
/**
 * Success handler function
*/
function getDataByIdSuccess(result){
  //do something specific with the result
 
}
/**
 * Failure handler function
*/
function getDataByIdFailure(result){
   //handle the failure case
}

In this code our ajax function getDataById has its success and failure blocks hardcoded into it. An improvement would be to pass those in as parameters to the now more generic ajax call.

//call the ajax call
getDataById(1,getDataByIdSuccess,getDataByIdFailure);
 
function getDataById(id,success,failure){
     //spawn the ajax call in library of your choice
     doAjax(connectionInfo,success,failure);
}
/**
 * Success handler function
*/
function getDataByIdSuccess(result){
  //do something specific with the result
 
}
/**
 * Failure handler function
*/
function getDataByIdFailure(result){
   //handle the failure case
}

This goes a long way towards making the success method generic. For many applications this is enough but this solution lacks the ability to pass additional parameters to the success/failure function. Sure we could use global variable to do this, but since this is asynchronous, unless we implement some sort of locking mechanism, we can’t guarantee the values will still be the same when we go to read them. To get around this we have our handler functions accept an args object. Obviously your success function needs to produce different results depending on the arguments, otherwise it is fine to hard code those args into the success function itself.

//call the ajax call
argObject = new Object();
argObject.containerDiv = "foo";
argObject.linkDiv ="bar";
getDataById(1,getDataByIdSuccess,getDataByIdFailure,argObject);
 
function getDataById(id,success,failure,argObject){
     //spawn the ajax call in library of your choice
     doAjax(connectionInfo,function(result){
 
                                           success(result,argObject);
                                        }
                                        ,function(result){
 
                                           failure(result,argObject);
                                        });
              success,failure);
}
/**
 * Success handler function
*/
function getDataByIdSuccess(result,args){
  //do something specific with the result and use the passed arguments
 var container =  args.containerDiv;
 var link = args.linkDiv;
document.getElementById(container).innerHTML = "
	<li>"+result.title+"</li>
";
 
}
/**
 * Failure handler function
*/
function getDataByIdFailure(result,args){
   //handle the failure case
}

Using this method you can maintain a single generic ajax call that takes in the handler functions and additional parameters to pass along without having to resort to a global variable and the problems this introduces.

This method makes it very easy for you to separate your presentation code from your data code which will make your system easier to maintain.

JQuery Annoyances – Overriding “this”

Posted in Javascript on January 27th, 2009 by Alan Hietala – Be the first to comment

I’ve been working on a simple javascript MVC pattern that uses jQuery in the view code and have come across an interesting side effect of using jQuery and javascript objects.

MyView(clickCallback){
    this.clickCallback = clickCallback; //callback function in the controller
    this.renderView = function(){
         $("#somedivid").click(function(){
            //do something
            this.clickCallback(); // unfortunately jQuery overrides this
                                           //so this doesn't work
        });
    }
}

In order to work around this problem we have to assign the callback method to a local variable that is accessible from within the jQuery block.

MyView(clickCallback){
    this.clickCallback = clickCallback; //callback function in the controller
    this.renderView = function(){
        var clCallback = this.clickCallback;
         //start the jquery section
         $("#somedivid").click(function(){
            //do something
            clCallback(); // this will now call the appropriate callback
        });
    }
}

Since the local variable contains the callback we can now work around the problem of jQuery overriding the meaning of “this”. Most of the time when you are doing simple things the overridden “this” is very useful. Unfortunately when you want to access an instance variable from within a block of jQuery, you have to resort to a hacky work around.

CSS Classes as a Javascript Interface

Posted in Javascript on January 11th, 2009 by Alan Hietala – Be the first to comment

In many frameworks, display code is separated from business logic. An MVC pattern is one of the many ways to accomplish this. When writing javascript featuring heavy UX changes such as in a sidebar it is very helpful to split up the data/state code from the pure animation code.

To accomplish this we use the CSS class as the interface between the two. This has the added benefit of letting two different developers work on those aspects separately with a minimum of integration issues in the end. Additionally this gives us the ability to reuse our ajax calls in different contexts.

In the following example we have a simple ajax enabled sidebar that loads data when a section is opened. The “interface” is the structure of the sidebar defined beforehand in xhtml.

 <div class="sidebar">
        <div class="sidebaritemheader">
        </div>
       <div class="sidebaritem">
        </div>
        <div class="sidebaritemheader">
        </div>
       <div class="sidebaritem">
        </div>
</div>

This simple layout defines the interface that the animation and data aspects of the javascript will use. Each part needs simply attach their events to the appropriate element and javascript will fire them when needed. This example uses JQuery but you can use your javascript framework of choice, or even do everything from scratch should you me a masochist.

     /**
      * Animation javascript funtion
      */
     function animate(){
       //animation code here
     }
    // populates the sidebar data into the given container which is a jquery object
    function populateSidebarData(xmlResult,sender){
        //generate sidebar data items xhtml 
          //fill this out yourself         
 
        //calculate the insert container from the sender object
         var sidebarItems = $(".sidebar").find("sidebaritem");
         var index = $(".sidebar").find(".sidebaritemheader").index(sender);
         var container = sidebarItems.eq(index);
 
        //insert it into the container
       container.innerHTML = sidebarInsert;
    }
 
   //getData method
function getData(populateMethod,sender){
   .ajax(.....
    //in the success section
        ,success
              populateMethod(xmlResult,sender);
    }
}
   //main onload method
    $(document).ready(function(){
 
         $("sidebaritemheader").click(animate);
         $("sidebaritemheader").click(function(){
              getData(populateSidebarData,$(this));
 
          });
    });

as you can see the animation code and the data code are nicely separated and could even be tackled by 2 different developers if the complexity demands it. With this decoupling achieved you can be sure that any changes to the data code are not going to have repercussions in the animation code which I’m sure you’ll agree is a very good thing.

If you want to decouple this even farther, you can tell your designer to use a completely separate set of css classes for the visual markup and to not touch the data related ones. This ensures that your designer cannot inadvertently break the other ajax on the page.