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