Category Archives: ajax

Playing with Pusher


A couple of weeks ago Ben Nadel did a few excellent blog posts about Pusher, a service in beta stages that offers “real time client push to HTML5 browsers” that support web sockets and falls back to a flash plug-in on browsers that do not support web sockets.

This evening I finally had a few minutes to play around with it between working on other projects.  I thought it would be a bit of an ordeal getting things going, but it was surprisingly fast.  Pusher is in open beta so getting an account setup took all of a minute (literally).

Since that was far too easy, the next hurdle would be communicating with the service.  If you check Ben’s demo code quite a bit of it was more or less preparing the data to be sent to Pusher so it could be pushed to the clients.  Ben had a link to pusher.cfc by Bradley Lambert which actually alleviated the hassle.

That is the heavy lifting of setting up your pusher app.  I did actually write a few lines of code to setup the remote facade for interacting with pusher.cfc, aside from that everything just worked out of the gate.  For those interested, the remote facade for pusher.cfc.

<cfcomponent output="false">

 <cffunction name="push" access="remote" returntype="any" returnformat="json">
  <cfargument name="channel" type="string" required="true">
  <cfargument name="event" type="string" require="true">
  <cfargument name="data" type="any" required="true">
  <cfargument name="socketID" type="string" required="false" default="">
  <cfscript>
   var push = getPusher().triggerPush(arguments.channel, arguments.event, serializeJSON(arguments.data), arguments.socketID);
   return push;
  </cfscript>
 </cffunction>

 <cffunction name="getPusher" access="private" returntype="any">
  <cfscript>
   var pusher = createObject("component", "com.pusher");
   return pusher;
  </cfscript>
 </cffunction>

</cfcomponent>

I bound to a few simple events on a test page so I could make sure everything was working, but I did not get much further this evening.  Before I started going wild binding to events, I wanted to take a little time and think things out a little bit.  What I will say is, if you are looking for real time client push and you don’t feel like dealing the the added complexity of running Blaze/LCDS or the other alternatives, I cannot think of a better way of spending 30 minutes.

Easy jQuery multifile uploader


I needed a quick and dirty multi-file uploader for a site, but I did not want to install another plugin or a flash uploader.  I am using the jQuery form plugin already to handle AJAX form submissions so I will hook to that to upload my files to the site.

My method basically uses jQuery to inject a form with a filefield into the DOM.  I bind to the onchange event of the filefield so when a file is added the current file field is hidden, insert a new blank file field, and update a list of queued files waiting to be uploaded.  When the user hits the “Upload Files” button, I iterate through all the “input:file” elements using jQuery and submit the form using the jQuery form plugin with ajaxForm().  Of course, you can remove a file from queue as well by clicking on the X in the queue list.

It is an inelegant solution, but it does work.  Here is the code if you want to give it a try:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Multi-file upload</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="/js/jquery.form.js"></script>
</head>

<body>
 <div id="uploadContainer"></div>
 <input id="btnSubmit" type="button" value="Submit Files" onclick="submitLoop();" />
 <div id="fileInfo"/>

 <script language="javascript">
  $(document).ready(function(){
   $container = $('#uploadContainer');
   $info = $('#fileInfo');
   count=0;                            
   addUpload();
  });
 function addUpload(){
  count++;
  $('form').hide();
  $container.append('<form id="uploadForm-' + count +'" action="ajaxProxy.cfc?method=upload" enctype="multipart/form-data"><input id="file-' + count + '" name="filename" type="file" onchange="addUpload();" /></form>');
  showFileInfo();
 }
 function removeItem(id){
  if( $('#' + id).length){
   $('#' + id).remove();  
   showFileInfo();
  }
 }
 function showFileInfo(){
  $info.html('');
  $('input:file').each(function(){
   if( $(this).val().length ){
    $info.append('<div id="display-' + $(this).attr('id') + '"><a href="#" onclick="removeItem(\'' + $(this).parent().attr('id') +'\')">X</a> '  + $(this).val() + '</div>');
   }
  });
 }
 function submitLoop(){
  $('input:file').each(function(){
   var currItem = $(this).attr('id');
   if($(this).val()){
    $(this).parent().ajaxForm({
     async: false,
     success: function(data){
      var incoming = $.parseJSON(data);
      $('#display-' + currItem).append(' <strong>' + incoming.svrMessage + '</strong>');
     }
    }).submit();
   }
  });
 }
 </script>
</body>
</html>

Simple chat app using jQuery and ColdFusion


Way back in the day I was working on a jQuery game I called CFMud. As the name alludes to, it was to be a multi-user dungeon that would allow you to roam around “the world” and gain experience. One of the key components of the UI was the chat interface. I was just getting in to jQuery and ajax at the time so I never really worked all the kinks out of the system then life intervened and I have never picked the project back up (sorry Josh 😛 ).

Yesterday a co-worker mentioned that she was looking for a simple little chat application so I figured I would give it a shot. I threw together an extremely quick, extremely basic little demo. The application itself is comprised primarily of three pieces: the index.cfm file for the user interface, an application-scoped CFC that acts as the “chat server”. and finally an ajaxProxy.cfc that acts as a facade for remote calls.

To start, just call up the index.cfm you will need to enter a user name to use in the chat window. Enter a name and click on the “Set Name” button. This will then bring up the main chat window and currently updates every five seconds. I have tested it in the main browsers; FireFox, Chrome, and with much swearing, Internet Explorer. For some reason, IE likes to cache remote calls to CFC’s as well. Go figure.

The “chat server” is actually just an array stored in server memory.  Currently it is configured to store 100 messages, it will purge out the oldest message if the current chat log goes above this.  Also, to keep down the amount of data being transferred from the server, each client remembers the message id it received.  When the next call to get messages occurs, it only gets new messages.

If you would like to check it out, I have it available for download here: http://dl.dropbox.com/u/868773/chat.zip.  It is hardly worthy of an RIAForge project, but maybe I will play around with it some more later on.

To see it in action: http://demos.kisdigital.com

Debugging ajax calls with ColdFusion


I was debugging a video conversion application this afternoon that relies heavily on ajax to move the user along in the conversion process.  After each step in the process another ajax call is fired off to continue to the next step.  When things are working as expected it is a beautiful thing, when it does not things tend to get interesting.  I had some code inside my CFC and the server was throwing a hard error, needless to say my response codes were never returned back to my ajax call from the remote method.  The user would end up staring at a processing screen that would never go away.

To get around this I standardized all my ajax calls.  No matter what information I am expecting back from my CFC, I always pass back a svrStatus variable and a svrMessage variable.  Server status is the variable I check to make sure everything went as planned, if it is not 0 I know there was a problem.  The svrMessage variable is what I want the users to see so they are not scratching their heads wondering what is going on.

I whipped up a quick demonstration.  It is definitely nothing new, but I thought maybe it would help someone out.

Our basic page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Ajax debug</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
</head>

<body>

<div id="results" />

<script type="text/javascript">
 $(document).ready(function(){

  $res = $('#results');

  for(var i = 0; i < 3; i++){
   $.ajax({
    url    : 'remoteProxy.cfc',
    data   : {
    method : 'remoteFunction',
    pass   : i
   },
   async   : false,
   success : function(data) {
    incoming = JSON.parse(data);
    $res.append( '<strong>Pass ' + i + ':</strong> ' + incoming.svrMessage + '<br/>');
   }
  });
 }

 });
</script>
</body>
</html>

remoteProxy.cfc:

<cfcomponent output="no">

 <cffunction name="remoteFunction" access="remote" returntype="struct" returnFormat="JSON">
  <cfargument name="pass" type="numeric" required="yes"/>
  <cfset var respsone = structNew()/>
  <cftry>
   <cfset response['svrStatus'] = "0"/>
   <cfset response['svrMessage'] = "Method completed successfully"/>

   <cfif arguments.pass eq 1>
    <cfthrow message="Doh!  Something broke!"/>
   </cfif>
   <cfcatch type="any">
    <cfset response['svrStatus'] = "-1"/>
    <cfset response['svrMessage'] = cfcatch.Message/>    
   </cfcatch>
  </cftry>
  <cfreturn response>
 </cffunction>

</cfcomponent>

There is nothing too complicated going on here.  The web page makes a call to our remote CFC and in this case it is hard-coded to throw an error on the second pass, simulating an error condition.  The whole method is wrapped in a CFTRY block so if something did occur while the method was executing it would fire the CFCATCH block.  The CFCATCH block sets the svrStatus to -1 letting me know that there was an error and it also sets the svrMessage variable to CFCATCH.Message so we will know the root cause of the problem.

The web page itself is not that complicated either.  After making the ajax call we parse the data returned into JSON.  At this time we could simply look at the svrStatus variable see if we have an error and display a message if so.

Any other tips and tricks for debugging ajax calls?