Monkey Patching Dojo’s Menu Dijit

By  on  

If you haven't already read Bryan Forbes' Monkey Patching tutorial, I want you to do so right now. Leave this blog and do it. Why? Because it's an invaluable tool in safely patching installs of your favorite JavaScript framework. In a nutshell, "Monkey Patching" is the process of "extending or modifying the runtime code of dynamic languages (e.g. Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc.) without altering the original source code."

Why is that important? A number of reasons:

  1. You don't touch a JavaScript library's packaged code, making upgrading your library much more straight-forward.
  2. You don't need to remember where you patched that one thing that one time.
  3. Your patches are much more portable.
  4. You don't need to wait until your favorite library's team updates the functionality (...if they every do).

Where am I going with all of this? I recently needed to Monkey Patch a core Dojo/Dijit functionality. Between Dojo 1.3.2 and 1.4.3, the Menu class changed in that submenus needed to be clicked to pop out instead of the usual hover trigger. Here's how I MP'ed the Menu class to do what I wanted it to.

The Dojo JavaScript

/* Popup Menu Open on Hover */
(function() {
	dijit.Menu.prototype.allowSubmenuHover = true;
	dijit.Menu.prototype.popupDelay = 500;
	dijit.Menu.prototype.onItemHover = function(item) {
		if(this.isActive || this.allowSubmenuHover) {
			this.focusChild(item);
			if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
				this.hover_timer = setTimeout(dojo.hitch(this, '_openPopup'), this.popupDelay);
			}
		}
		if(this.focusedChild){
			this.focusChild(item);
		}
		this._hoveredChild = item;
	};
})();
/* popup hover patch end */

I modified the dijit.Menu class' prototype, adding two options: allowSubmenuHover and popupDelay (the timer). I then modify the onItemHover method to account for the two new options. Now submenus will pop out when you hover over their label. FTW!

Like I said, even if you aren't a Dojo developer, you really should read Bryan's post. The method described in his post applies to *any* JavaScript code: jQuery, Dojo, MooTools, YourLib, whatever. His post even saves the original prototype and calls it once the custom work is done -- even better! I promise it will make you a better JavaScript developer!

Recent Features

  • By
    5 More HTML5 APIs You Didn’t Know Existed

    The HTML5 revolution has provided us some awesome JavaScript and HTML APIs.  Some are APIs we knew we've needed for years, others are cutting edge mobile and desktop helpers.  Regardless of API strength or purpose, anything to help us better do our job is a...

  • By
    Page Visibility API

    One event that's always been lacking within the document is a signal for when the user is looking at a given tab, or another tab. When does the user switch off our site to look at something else? When do they come back?

Incredible Demos

Discussion

  1. Or you could just use MooTools and make a subclass. MooTools FTW!

  2. @Daniel15: You can subclass these in Dojo as well, but this allows me to not need to go through the rest of the app and change code to the subclass’ name.

  3. Thanks for the tutorial. How does this approach differ (if at all) for dojo 1.7?

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!