One of the popular design pattern documented by Gang of Four is the Chain of Responsibility pattern. The Chain of Responsibility pattern allows decoupling between objects by passing a request from one object to the next in a chain until the request is recognized. It is about avoiding coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.

This post talks about my take on implementing Chain of Responsibility pattern in JavaScript. Here we take an example of a wizard where functionality for each tab in the wizard is handled by separate JavaScript objects which we call the tab objects and there is a single wizard object that receives the request and passes it to the object that takes care of the current tab functionality.

There is a single parent wizard page containing UI that defines the chrome of the wizard and the previous and next buttons. In an external JavaScript file, we write the code that handles the wizarding functionality. We define a single wizard object using constructor function:

var Wizard = function(arr) {

this.tabObjects = arr;

……………

}

The constructor function accepts an array of tab objects of the form:

var abc = {

name:'Step 1', scriptFile:'/jscripts/step1.js'

}

var mno = {

name:'Step 2', scriptFile:'/jscripts/step2.js'

}

var xyz = {

name:'Step 3', scriptFile:'/jscripts/step2.js'

}

var myWizard = new Wizard([ abc, mno, xyz]);

Each of these objects has two properties – ‘name’ which is the text to be shown on the tab and the ‘scriptfile’ which points to the location of the JavaScript file that implements the functionality for that tab.

The constructor function calls an init method that constructs a tab for each of the tab object and asynchronously downloads each script file of each tab.

Wizard.prototype.init = function() {

for (var i = 0; i < tabsObjects.length; i++) {

$.getScript(this. tabsObjects[i].scriptFile, (function(y, z) {

function makeClosure(a, b) {

return function() {

a.htmlLoaded = false;

$("#div" + b).load(a.htmlFileName, function() { a.init(); });

}

}

return makeClosure(y, z);

})(this.tabsObjects[i], i));

}

$('.nextButton').click(this.nextButtonClicked);

$('.prevButton').click(this.previousButtonClicked);

this.currentTabIndex = 0;

this.currentTabObj = this.tabsObjects[this.currentTabIndex];

}

‘currentTabIndex’ and ‘currentTabObject’ are additional properties on the Wizard object that hold the index and object of the current tab, respectively. Note we have use jquery here. $(“#div” + b) refers to the divs that we create for each tab. The variable b is the index for each tab.

In the script files of each tab, we further augment the corresponding tab object with additional properties and methods.

abc.htmlFileName = escape('/htmls/step1.htm');

abc.loadPageData = function(obj) {...}

abc.validatePageData = function(obj) { return true; }

abc.savePageData = function(obj) {...}

abc.init = function(obj){...}

Each file at minimum augments the corresponding tab object with a property htmlFileName which points to the file containing the html for that tab and four methods – loadPageData which is called when the tab is loaded, validatePageData which is called when user clicks next on the tab and if it returns true, savePageData is called. ‘init’ is called when the html file is downloaded and loaded into the wizard DOM.

The Wizard defines an empty object called:

var wizardGlobalObject = {};

This object is passed to each of the above methods as argument. This object is passed around from tab to tab and basically will hold all the information the user enter in the tabs. We can define the content of this object with the fields that we want to pass from tab to tab.

Now we define functions on wizard object that handles navigation:

Wizard.prototype.processCurrentTab = function() {

this.currentTabObj.loadPageData(wizardGlobalObject);

}

Wizard.prototype.nextButtonClicked = function() {

if {

(this.currentTabObj.validatePageData(wizardGlobalObject)) {

this.currentTabObj.savePageData(wizardGlobalObject);

this.currentTabIndex++;

this.currentTabObj = this.tabsObjects[this.currentTabIndex];

this.processCurrentTab();

}

}

Wizard.prototype.previousButtonClicked = function() {

this.currentTabIndex--;

this.currentTabObj = this.tabsObjects[this.currentTabIndex];

this.processCurrentTab();

}

‘processCurrentTab’ method calls the loadPageData of the current active tab. This method is called immediately after a tab becomes active i.e. the user lands on the tab. The method reads the content from the object and populates the fields of the tab accordingly. ‘nextButtonClicked’ is called when user clicks on the next button. The method calls validateData method passing in the wizard global object. The method checks whether data for all compulsory fields are entered for each tab. If validated successfully, the method returns true else false. If true, savePageData is called which stores the data entered in the global object. The current tab index is incremented and loaded. previoisButtonClicked is called when previous button clicked. It decrements the currentTabIndex and load previous tab. The final version of the constructor method looks like following:

var Wizard = function(objsArray) {

this.tabsObjects = objsArray;

this.currentTabObj = {};

this.currentTabIndex = -1;

this.init();

}

As user moves from one tab to next, the wizard object loads corresponding tab objects and passes on the processing to these objects. That is to say, the responsibility is chained from wizard objects to tab objects. In some manner, we even employed factory pattern too for getting the tab object for the current tab based on the tab index.