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
    Regular Expressions for the Rest of Us

    Sooner or later you'll run across a regular expression. With their cryptic syntax, confusing documentation and massive learning curve, most developers settle for copying and pasting them from StackOverflow and hoping they work. But what if you could decode regular expressions and harness their power? In...

  • By
    Camera and Video Control with HTML5

    Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API...

Incredible Demos

  • By
    Build a Toggling Announcement Slider Using MooTools 1.2

    A few of my customer have asked for me to create a subtle but dynamic (...I know...) way for them to advertise different specials on their website. Not something that would display on every page, but periodically or only the homepage. Using a trick...

  • By
    CSS Counters

    Counters.  They were a staple of the Geocities / early web scene that many of us "older" developers grew up with;  a feature then, the butt of web jokes now.  CSS has implemented its own type of counter, one more sane and straight-forward than the ole...

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!