JavaScript Template Method Pattern

During my recent client engagement we have been heavily involved in using JavaScript for our PhoneGap application.  As such, we have had to find ways of doing things heavily dependent on context, that is the state of the application.

I recently discovered a way to implement the “Template Method Pattern” in JavaScript that has served me quite well, so I figured I would share it here.

Android Back Button

During the development of our PhoneGap application we had need to handle the back button.  Our goal was to handle it in such a way so that it felt natural to the end user who would be used to their existing Android applications.  This included a couple of necessary cases:

  • If there is an existing obscurance on the screen, it should be dismissed
  • If allowed the application should “go back” to the most recent available page in the stack.  If none is available, the application should exit

Using the standard way of handling back within a PhoneGap application, we discovered that for system type obscurances (keyboard, system alerts, etc) are handled outside PhoneGap, so the back button event is never raised in this case.

To handle the second case, I implemented a Page Stack type subsystem which tracks history and manages the stack.  Very basic and nothing more than a wrapped array.  Because, in certain cases, a custom obscurance can be visible, that is a dialog or perhaps a datepicker, we want the back button to be able to ask the current page if it should go back in the stack or take other action.

This is where the Template Method Pattern is useful.  If we had to code for all situations inside the back button event handler, the code would quickly spiral out of control.  So we want to use the Template Method Pattern to first allow the page to take action on its own and then to indicate if we should still go back in history.

A Real Template Method

If you are familiar with the template method in OO, you know that generally you define an abstract or virtual method and then call that method from with another.  The idea is that this method gives you a “hook” that allows custom functionality at certain points.  In JavaScript, we have to take a slighty different approach.  Start by defining the structure of your methods name.

In the case of the client project, we elected to go with _handleBackButton.  So if I was on a page called TimeConfirm.html, I would call the method “timeconfirm_handleBackButton”.  This method would need to perform any actions locally and then indicate if the previous page should be loaded.

As is it so happens, all JavaScript methods available are callable through window as if they were in an associative array.  The following code details our method which handles the press of the back button that does not dismiss a system type obscurance.

   1:  function _handleBackButton()
   2:  {
   3:    var currentPageName = $.getCurrentPage().replace(/\.html$/, "");
   4:    var methodName = currentPageName + "_handleBackButton";
   6:    if (window[methodName] != undefined)
   7:    {
   8:      var result = window[methodName];
   9:      if (!result)  return;   // stop processing the back button
  10:    }
  12:    var previousPage = $.pageStack.pop();
  13:    if (previousPage == null)
  14:    {
  15:;   // exit the app
  16:      return;
  17:    }
  19:    $.changePage(previous);
  20:  }

.csharpcode, .csharpcode pre
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
background-color: #f4f4f4;
width: 100%;
margin: 0em;
.csharpcode .lnum { color: #606060; }

The first thing we do is get the current page (which will be the filename with .html at the end) name.  Using this name we build the name of the method (methodName) and check if its available.  Traditionally in Template Method Pattern the method must be defined, though sometimes we can use a default implementation.  In this case, if the method does not exist, we do not use it, the code is simply by passed.

Whats important to note here is how the return of the “special” method is used.  If the method returns true then the back button will continue to function.  This is because in some cases you may want to save page state and continue to go back.  In that case, you still need a “hook” but would want to back button to function as normal.

So that’s it.  I have found this very useful and so far not a detriment to performance.  It certainly beats trying to define the variety of cases in the same method.  Hopefully this can be of use in your applications.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s