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
    Responsive and Infinitely Scalable JS Animations

    Back in late 2012 it was not easy to find open source projects using requestAnimationFrame() - this is the hook that allows Javascript code to synchronize with a web browser's native paint loop. Animations using this method can run at 60 fps and deliver fantastic...

  • By
    5 HTML5 APIs You Didn’t Know Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for so long that a basic feature...

Incredible Demos

  • By
    CSS Tooltips

    We all know that you can make shapes with CSS and a single HTML element, as I've covered in my CSS Triangles and CSS Circles posts.  Triangles and circles are fairly simply though, so as CSS advances, we need to stretch the boundaries...

  • By
    MooTools dwCheckboxes Plugin

    Update / Fix: The checkboxes will no longer toggle when the "mouseup" event doesn't occur on a checkbox. Every morning I wake up to a bunch of emails in my Gmail inbox that I delete without reading. I end up clicking so many damn checkboxes...

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!