Dojo, Dijit, Dropdowns, and _aroundNode

By  on  

The Dojo Toolkit's awesome UI framework, Dijit, has loads of awesome widgets to allow developers to quickly create themed, feature-rich web applications. Dijit provides form widgets, layout widgets, dropdown-based widgets, and much more. What's nice about Dijit is that there's so much functionality provided that you don't need to code everything yourself. The down side of that? That it can be difficult to find the undocumented pieces of functionality required to accomplish your goal.

One case recently came up where I was working on a widget that extended dijit.form.FilteringSelect. My custom widget displayed messages under the widget's INPUT instead of the default tooltip behavior. The problem that introduced was that the widget's dropdown displayed a full 20 pixels under the INPUT node, so the two elements looked "detached." My assumption was that this was happening because the domNode grew in height because of my template change.

This is where it became difficult to know exactly where to look to fix the issue. I attempted a hack of adding margin-top: -20px to the FilteringSelect's dropdown node, which worked, but if the error text went down to two lines, the dropdown would still be detached -- obviously not the reliable solution. Where to look next?

I knew that dijit.popup manages the position of a popup, so that was my next stop. dijit.popup accepts one argument (an object) about the popup, with information about the widget, the node to pop up, an around property telling the method where to fit the popup by, and more. Seeing that, I needed to figure out where FilteringSelect's around setting was coming from. I also knew there is no property named around on the FilteringSelect widget, so more investigation was needed.

Within the creation signature for FilteringSelect, I saw that dijit._HasDropDown is a mixin. Looking at the _HasDropDown resource, I saw a method called openDropdown and right at the top of that method I found exactly what I needed:

openDropDown: function(){
	// summary:
	//		Opens the dropdown for this widget.   To be called only when this.dropDown
	//		has been created and is ready to display (ie, it's data is loaded).
	// returns:
	//		return value of dijit.popup.open()
	// tags:
	//		protected

	var dropDown = this.dropDown,
		ddNode = dropDown.domNode,
		aroundNode = this._aroundNode || this.domNode,
		self = this;
		
	// more...
	

The _aroundNode that was being passed to dijit.popup is the domNode unless a special _aroundNode property is explicitly set. Now I could set the _aroundNode property to my widget's focusNode (the INPUT):

this._aroundNode = this.focusNode;

This small addition fixes the detachment issue, directing dijit.popup to open the dropdown around the INPUT element and not the entire domNode.

These type of exercises are very helpful in both learning a framework and improving your debugging skills. Undocumented properties and features are present in any set of code, so the ability to trace through and find what you need is hugely important. It definitely was in this case!

Recent Features

  • By
    Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event...

  • By
    Serving Fonts from CDN

    For maximum performance, we all know we must put our assets on CDN (another domain).  Along with those assets are custom web fonts.  Unfortunately custom web fonts via CDN (or any cross-domain font request) don't work in Firefox or Internet Explorer (correctly so, by spec) though...

Incredible Demos

  • By
    Sexy Opacity Animation with MooTools or jQuery

    A big part of the sexiness that is Apple software is Apple's use of opacity. Like seemingly every other Apple user interface technique, it needs to be ported to the web (</fanboy>). I've put together an example of a sexy opacity animation technique...

  • By
    Introducing LazyLoad 2.0

    While improvements in browsers means more cool APIs for us to play with, it also means we need to maintain existing code.  With Firefox 4's release came news that my MooTools LazyLoad plugin was not intercepting image loading -- the images were loading regardless of...

Discussion

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