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
    Create a CSS Cube

    CSS cubes really showcase what CSS has become over the years, evolving from simple color and dimension directives to a language capable of creating deep, creative visuals.  Add animation and you've got something really neat.  Unfortunately each CSS cube tutorial I've read is a bit...

  • By
    From Webcam to Animated GIF: the Secret Behind chat.meatspac.es!

    My team mate Edna Piranha is not only an awesome hacker; she's also a fantastic philosopher! Communication and online interactions is a subject that has kept her mind busy for a long time, and it has also resulted in a bunch of interesting experimental projects...

Incredible Demos

  • By
    jQuery Comment Preview

    I released a MooTools comment preview script yesterday and got numerous requests for a jQuery version. Ask and you shall receive! I'll use the exact same CSS and HTML as yesterday. The XHTML The CSS The jQuery JavaScript On the keypress and blur events, we validate and...

  • By
    Duplicate the jQuery Homepage Tooltips

    The jQuery homepage has a pretty suave tooltip-like effect as seen below: The amount of jQuery required to duplicate this effect is next to nothing;  in fact, there's more CSS than there is jQuery code!  Let's explore how we can duplicate jQuery's tooltip effect. The HTML The overall...

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!