November 26, 2010

Javascript Event Model

A while ago I was working on a proof of concept for a mobile web application, and I realized that despite my use of a well-known JS framework I needed to create a few custom pieces to get all of the functionality I needed into the app.

One of the custom pieces I needed to create was an event model for my various custom objects to use during the application lifecycle, to broadcast changes in things such as network status.

Creating the event object itself was easy enough:

Event = function(config) {

     this.config = config;
     this.name = config.name;
     this.subscribers = [];

     this.attachListener = function(scope,func) {
            this.subscribers.push({s:scope,f:func});
     };

     this.dispatchEvent = function(sender, args) {
            for(i=0;i<this.subscribers.length;i++){
                 var callback = this.subscribers[i];
                 callback.f.apply(callback.s,arguments);
           }
     };
}


An event object takes a config object as its only parameter. The minimum requirement for the config object is that it have a name property, however it can obviously carry with it other information as well. The attachListener function does what you might expect: it takes an object for scope and a function of the scoped object to be used as a callback. Finally, the dispatchEvent function calls the callback method for each subscriber, within the scope specified by the subscriber.

Other javascript objects can utilize the Event object to dispatch events based on changes in state. Here's a simple example of one such object:

MyEventCaller = function() {

      this.myEvent = new Event({name:"myEvent"});

      this.callMyEvent = function(msg){
            this.myEvent.dispatchEvent(this,{message:msg});
      };
}


The MyEventCaller object has one property, myEvent, and one method, callMyEvent, which dispatches an event with a custom message. Now to complete the model, all we need is a listener:

MyEventListener = function() {
       this.onMyEvent = function(sender, args){
             alert(args.message);
       };
}


Now that we have our event, caller, and listener objects set up, we can write a script that uses them:

var caller = new MyEventCaller();
var listener = new MyEventListener();

caller.myEvent.attachListener(listener, listener.onMyEvent);

caller.callMyEvent("Hello world!");


So what happens here is that we've created an instance of our caller and our listener, and we've attached the listener's onMyEvent function to the caller's myEvent object. In the final line we've called the caller's callMyEvent function with a message. The callMyEvent function dispatches myEvent, which calls the callback functions that have registered to listen to it. As a result, we have this:


Of course, we can just as easily do away with our listener object and attach a listener function to our caller inline:

var caller = new MyEventCaller();

caller.myEvent.attachListener(this, function(sender, args){alert(args.message);});
caller.callMyEvent("Hello inline world!");


And, as expected, we get the following result:


I hope that you find this event model helpful for creating custom events and listening for them from other objects. As always, please feel free to leave comments or questions!

November 23, 2010

Create a Randomly Generated String of Arbitrary Length in PHP

Today I realized that I needed to create a method for generating a pseudo-random string from a constrained set of symbols. Rather than immediately consult Google for code, I decided to come up with the function myself. Hopefully it's helpful for some folks out there who opt to Google :)

Oh, and if you see anything that can be improved with this code please leave a comment!

//GetCharacterPool returns a constrained set of ASCII characters, consisting of
//A-Za-z0-9 and selected symbols.
function GetCharacterPool(){

      $charpool = array( 33, 35, 36, 37, 38, 94, 95, 126 );
     
      for($i=48;$i<=57;$i++){
          $charpool[] = $i;
      }
      for($i=64;$i<=90;$i++){
          $charpool[] = $i;
      }
      for($i=97;$i<=122;$i++){
          $charpool[] = $i;
      }
      return $charpool;
}


//GenerateRandomString generates a pseudo-random string of $length characters.
function GenerateRandomString($length){

      $rstring = "";
      $pool = GetCharacterPool();
      $rmin = 0;
      $rmax = count($pool)-1;


      for($i=0;$i<$length;$i++){
          $rnum = mt_rand($rmin,$rmax);
          $c = chr($pool[$rnum]);
          $rstring.= $c;
     }

     return $rstring;
}

November 17, 2010

jQueryUI plugin: Highlight and Error Alerts

So I've been working with jQuery for a while and have been digging into jQueryUI lately as well. I found rather quickly, however, that there is no built-in method for creating a Highlight or Error alert like those shown in the jQueryUI themeroller. So, I've created a very simple plugin to use specifically for that purpose:

(function($){
     $.fn.writeError = function(message){
        return this.each(function(){
           var $this = $(this);

           var errorHtml = "<div class=\"ui-widget\">";
           errorHtml+= "<div class=\"ui-state-error ui-corner-all\" style=\"padding: 0 .7em;\">";
           errorHtml+= "<p>";
           errorHtml+= "<span class=\"ui-icon ui-icon-alert\" style=\"float:left; margin-right: .3em;\"></span>";
           errorHtml+= message;
           errorHtml+= "</p>";
           errorHtml+= "</div>";
           errorHtml+= "</div>";

           $this.html(errorHtml);
        });
     }
})(jQuery);

(function($){
     $.fn.writeAlert = function(message){
        return this.each(function(){
           var $this = $(this);

           var alertHtml = "<div class=\"ui-widget\">";
           alertHtml+= "<div class=\"ui-state-highlight ui-corner-all\" style=\"padding: 0 .7em;\">";
           alertHtml+= "<p>";
           alertHtml+= "<span class=\"ui-icon ui-icon-info\" style=\"float:left; margin-right: .3em;\"></span>";
           alertHtml+= message;
           alertHtml+= "</p>";
           alertHtml+= "</div>";
           alertHtml+= "</div>";

           $this.html(alertHtml);
        });
     }
})(jQuery);


Note: I've put each function in its own closure to make it easier to integrate one or the other into your code.

The usage of the writeAlert function would be something like the following:

$("#myDiv").writeAlert("Form submitted successfully.");

And, of course, chainability is maintained, so you can animate your alert/error messages with something like the following:

$("#myDiv").writeAlert("Form submitted successfully.").fadeIn("slow").delay(3000).fadeOut("slow");

Happy coding!

November 16, 2010

JSON Support in IE8: Not So Much

These days most browsers out there have some kind of native support for working with JSON objects. Except Internet Explorer, that is.

Despite the fact that this blog post from 2 years ago states that there is native JSON support in IE8, when I tested my application in IE8 last week I still received the old familiar "JSON is undefined" error.

So, it seems that the native JSON support in IE8 is not really there, and thus I'm back to referencing json2 from http://json.org/json2.js instead.

November 15, 2010

Paper: Software Size and Effort Estimation: an Evaluation of Algorithmic and non-Algorithmic Techniques

Abstract: There is little debate over the observation that accurate planning and estimation at an early stage of the Software Development Life Cycle (SDLC) is critical to the success of any software project. However, there is also little debate that accurate prediction of the size of a software product at an early project stage is difficult to achieve. Since software product size estimation is a primary driver in the allocation of resources to a project, there is clearly significant value in conducting the software size estimation process in such a way that it yields the most accurate results possible. To date there have been many different methods proposed to conduct software size estimation, as well as controlled and observational studies performed to assess the effectiveness of the same. In this paper I shall provide a constrained review of the literature on software size estimation, including two relatively traditional methods and two novel methods for predicting software product size at early stages in the SDLC. Specifically, I shall describe the method, scope, advantages, and disadvantages of using Function Point Analysis, Estimation by Analogy, and Use Case Analysis for software size and effort estimation.

Driscoll-SoftwareSizeEstimation

February 17, 2010

How To Be Productive In An Open Office

I work in an open office environment, which just means that there are many people and few walls. As a result, it's sometimes easy to become distracted or be interrupted by co-workers and often difficult to get as much work done as I'd planned.

I've been trying to come up with some ways to make it easier to get work done at work rather than doing it when I come home at night, and here are some of the ideas I've generated. I can't promise they'll work for anyone else, but they seem to be working well for me so far.

1. Take Time to Make Time

When planning your day or week, set aside a block of time that you will dedicate to getting your work done without any interruptions. Setting this time aside now will help you later... like when you get that meeting planner at 10:00 for the meeting at 10:30. If that falls during your productive time, you can politely decline the request or suggest an alternative time.

2. Let Others Know You're Unavailable

Following Step 3 below will help to keep your co-workers from interrupting your productive time, but in an open office it's difficult to avoid some interruptions from people stopping at your desk for one reason or another. Before you begin working send out an email to your co-workers requesting that they not interrupt you during the time you've set aside for yourself. If you need to, tape a sign to the outside of your cubicle with the same request.

3. Disconnect and Shutdown

If the work you need to do doesn't require a computer, shut it down. No, really, I mean it. Turn the computer off. If you need your computer to do your work, here's what to do:
  • Sign out of all your IM/Twitter/etc. apps and close all browser windows that don't pertain to the task at hand (Looking at you, Mr. MySpace Creeper).
  • Close your email application. Really, it's okay, you won't miss anything more important than your third cousin's self-loathing status updates.
  • Turn off your cell phone. See above if you're worried about missing something important.
  • Put your office phone in Do-Not-Disturb mode.

4a. Relocate If You Can

Sometimes we all need a little peace and quiet, and that can be hard to come by in an open office. If you can take your work elsewhere and there is a quiet area available to you (a meeting room or vacant office, perhaps?), then head over that way to do your work. If you're lucky enough to get a room with a door, close the door.

4b. Build a Cocoon

If you just can't get away, do whatever you can to block out extraneous stimuli that will distract you. I find generally that putting some headphones on and shuffling through my classical or jazz playlist works well. You'll have to find what works best for you.

5. Do Your Work (!)

It's all too easy to distract ourselves sometimes. In order to be productive you need to have the focus and discipline necessary to do the work that's ahead of you and nothing else.

Hopefully these tips will help others to be more productive in an open office like mine, or just be more productive in general. If you have other tips to share about how to be more productive at work, please feel free to leave them in the comments section below.