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
    I’m an Impostor

    This is the hardest thing I've ever had to write, much less admit to myself.  I've written resignation letters from jobs I've loved, I've ended relationships, I've failed at a host of tasks, and let myself down in my life.  All of those feelings were very...

  • By
    CSS vs. JS Animation: Which is Faster?

    How is it possible that JavaScript-based animation has secretly always been as fast — or faster — than CSS transitions? And, how is it possible that Adobe and Google consistently release media-rich mobile sites that rival the performance of native apps? This article serves as a point-by-point...

Incredible Demos

  • By
    spellcheck Attribute

    Many useful attributes have been provided to web developers recently:  download, placeholder, autofocus, and more.  One helpful older attribute is the spellcheck attribute which allows developers to  control an elements ability to be spell checked or subject to grammar checks.  Simple enough, right?

  • By
    MooTools HTML Police: dwMarkupMarine

    We've all inherited rubbish websites from webmasters that couldn't master valid HTML. You know the horrid markup: paragraph tags with align attributes and body tags with background attributes. It's almost a sin what they do. That's where dwMarkupMarine comes in.

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!