Smart Hover Box for Mootools 1.2 v1

- Troy

v1

We have been hard at work developing some exciting projects, including this new release of Smart Hover Box. The biggest difference with the new version is that Hover Box is now a class instead of a function, giving you more control and extensibility. There are also a few new options, including “lockX” and “lockY,” allowing you to tell the box where to appear relative to the hover control. But like the previous version, you can leave the options blank to use the built in smart positioning (which will hover the box in the window quadrant with the most visible space).

Just like the previous release, to create a new hoverbox, simply take the ID of the element you want to be the hover control (an “a” tag for instance), then use that ID + the hover box suffix as the ID for the element you want to use as the hoverbox. If that wasn’t clear, please check out the sample code.

<a id="hover_control" href="#">Hover Here</a>
 
<div id="hover_control_smarthbox">This element is now a hoverbox.</div>

Demo

See smart hoverbox in action

Check out the previous version’s demos to seem more of hoverbox’s capabilities.

Features

  • create a hover box out of any html element
  • smart positioning will always show hover box in window quadrant with the most space
  • optional close button by adding a user defined class to any element
  • user defined x and y hover element offset (accepts negative integers)
  • user defined timeout after mouseleave event
  • flexible position “lock” (including top/bottom, left/right and any combination)

Installation:

To use the class, simply include the class file in the head of your html doc, after the mootools core. For more detailed instructions on installing and using mootools, please refer to our series, 30 days of mootools 1.2 tutorials.

Within the domready, you will need to initiate the new class and set your options (if you want to use something other than the default settings).

window.addEvent('domready', function() {
  var smartBox = new SmartHoverBox({ //initiate your new class here
    xOffset: 2 //set your options in here
    lockX: 'left' //set your options in here
  });
});

Configuration

Javascript

Here is the class. See the options and comments below:

Here is the Smart Hover Box javascript:

/* Smart Hover Box for Mootools 1.2
 * v1.0
 * Dedicated to public domain
 * troy@consideropen.com
 * www.consideropen.com/blog
*/
 
/* Usage:
 * to implement smart hover box,
 * take the id of the element you want to hover over,
 * then use the id +  the "smartBoxSuffix" as the id for the hover element.
 * Finally, create a new SmartHoverBox class and set any options you want to change.
*/
 
var SmartHoverBox = new Class({
	Implements: Options,
	options: {
		boxTimer           : 1000, // how many milliseconds before the box hides after mouseleave
                yOffset             : -10, // up and down offset in px - accepts negative ints
                xOffset             : -10, // left and right offset in px - accepts negative ints
		smartBoxSuffix    : '_smarthbox', //suffix that creates a hover box
		smartBoxClose    : 'smarthbox_close', //this class will add "close" click event to element
		lockY   	       : '', // 'top', 'bottom'
		lockX    	       : '' // 'left', 'right'
	},
	initialize: function(options) {
		this.setOptions(options);
		this.pos = [];
		this.smartBoxes = $$('[id$=' + this.options.smartBoxSuffix + ']');
		this.closeElem = $(document.body).getElements('.' + this.options.smartBoxClose);
		this.closeElem.addEvent('click', function(e){
			e.preventDefault();
			this.closeBox();
		}.bind(this)).setStyle('cursor', 'pointer');
		this.smartBoxes.setStyle('display', 'none');
		this.showHideBox();
		this.closeBox();
	},
	showHideBox: function(){
		this.smartBoxes.each(function(item){
			this.getCurrentBox(item);
 
			item.addEvent('mouseleave', function(){this.closeBoxTimer()}.bind(this));
			item.addEvent('mouseenter', function(){$clear(this.delay)}.bind(this));
			$(this.currentBox).addEvent('mouseleave', function(){this.closeBoxTimer()}.bind(this));
			$(this.currentBox).addEvent('mouseenter', function(){
				this.getCurrentBox(item);
				$clear(this.delay);
				this.smartBoxes.setStyle('display', 'none');
				item.setStyles({ display: 'block', position: 'absolute' }).setStyle('z-index', '1000000');				
 
				this.positioning(item, this.currentBox);
 
			}.bind(this)).setStyle('cursor', 'pointer');
		}.bind(this));
	},
	closeBoxTimer: function(){
		this.hideEm = function(){this.closeBox()}.bind(this);
		this.delay = this.hideEm.delay(this.options.boxTimer);
	},
	closeBox: function() {
		this.smartBoxes.setStyle('display', 'none');
	},
	positioning: function(currentItem, currentLink){
		this.pos.windowSize = $(window).getSize();
		this.pos.windowScroll = $(window).getScroll();
		this.pos.boxSize = currentItem.getSize();
		this.pos.inputPOS = $(currentLink).getCoordinates();
		this.pos.inputCOOR = $(currentLink).getPosition();
		this.pos.inputSize = $(currentLink).getSize();
		this.pos.halfWindowY = this.pos.windowSize.y / 2;
		this.pos.halfWindowX = this.pos.windowSize.x / 2;
		this.pos.inputBottomPOS = this.pos.inputPOS.top + this.pos.inputSize.y;
		this.pos.inputBottomPOSAdjust = this.pos.inputBottomPOS - this.pos.windowScroll.y
		this.pos.inputLeftPOS = this.pos.inputPOS.left + this.options.xOffset;
		this.pos.inputRightPOS = this.pos.inputPOS.right;
		this.pos.leftOffset = this.pos.inputCOOR.x + this.options.xOffset;
 
		if(this.pos.halfWindowY &lt; this.pos.inputBottomPOSAdjust &amp;&amp; this.options.lockY == 'none' || this.options.lockY == 'top') {
			currentItem.setStyle('top', this.pos.inputPOS.top - this.pos.boxSize.y - this.options.yOffset); //top
			if (this.pos.inputLeftPOS &lt; this.pos.halfWindowX &amp;&amp; this.options.lockX == 'none' || this.options.lockX == 'left' ) {
				currentItem.setStyle('left', this.pos.leftOffset); //top left
			}
			else { currentItem.setStyle('left', (this.pos.inputPOS.right - this.pos.boxSize.x) - this.options.xOffset); }; //top right
		}
		else {
			currentItem.setStyle('top', this.pos.inputBottomPOS + this.options.yOffset); //bottom
			if (this.pos.inputLeftPOS &lt; this.pos.halfWindowX &amp;&amp; this.options.lockX == 'none' || this.options.lockX == 'left' ) {
				currentItem.setStyle('left', this.pos.leftOffset); //bottom left
			}
			else { currentItem.setStyle('left', (this.pos.inputPOS.right - this.pos.boxSize.x) - this.options.xOffset);};//bottom right
		};
	},
	getCurrentBox: function(currentItem){
		this.currentBox = currentItem.getProperty('id');
		this.currentBox = this.currentBox.replace('' + this.options.smartBoxSuffix + '', '');
	}
});

Options

boxTimer

This sets the delay before the box disappears (int measured in milliseconds)

yOffset

Sets the up and down offset, will accept negative integers.

xOffset

Sets the left and right offset, will accept negative integers.

smartBoxSuffix

Sets the ID suffix that will make an element into a smartbox.

smartBoxClose

Sets the class name that will add a click event to close hoverboxes.

lockY

Acccepts ‘top’ or ‘bottom’ or can be empty. This will ‘lock’ the hover box, so if you lockY ‘top’ but leave lockX blank, the hoverbox will show up top-left or top-right, depending on which window quadrant has the most room.

lockX

Just like lockY, but accepts ‘left’ and ‘right’. If you use both in combination, the hoverbox will lock in the specified corner.

hoverbox close method

The new version also includes the method, closeBox. This lets close the hoverbox when another javascript event fires. To use the method, just state the var you created when you initialized the class, then tack on “.method();.”

//this will close any open hoverbox initiated by the smartBox class instance.
smartBox.closeBox();

HTML

Nothing has changed in regards to the html. To set add a hoverbox to an element, just add take the ID of the element you want to hover over, then add that ID + the hoverbox suffix to your new hoverbox. That’s it.

<span id="instructions">instructions</span>
 
<div id="instructions_smarthbox">
 
<ul>
 
	<li>Step one</li>
 
 
	<li>Step two</li>
 
 
	<li>Step three</li>
 
</ul>
 
</div>

Download

Download SmartHoverBox.js

Thanks and I hope you find it useful.

You can still download and check out the previous release, v0.11.

Creative Commons License
This work is dedicated to the Public Domain.

Bookmark and Share

Comments (14) Trackbacks (3)
  1. Tim B


    Thank you so much for all your help with Mootools, they've made a big difference in filling in the knowledge gap.
  2. BeN


    Nice blog, thanks for all.. i will be following the site
  3. 2o9


    Great Blog.
    because of your effort, I learned javascript from scratch in no time.

    Thanks.
  4. John Morris


    Excellent work and excellent class.

    One thing I noticed, while doing some compression work, was that the following line was missing a semicolon:

    this.pos.inputBottomPOSAdjust = this.pos.inputBottomPOS - this.pos.windowScroll.y

    This meant that compressing the code onto a single line, using Dean Edwards' Packer (http://dean.edwards.name/packer/), would cause an error, as the semicolon is required.

    I also have some modifications to the code that I should share, as I think they would benefit the Mootools community.
  5. Kareem


    Thanks for the script.

    Is it possible to change the styles of the boxes? Color, border, font etc? Does the hoverbox take the styles from the element I make a hoverbox element? Thanks.
  6. Dimitris


    Many thanks, works fine for me...
  7. Groover


    This looks like a great script, but I have just wasted 3 hours of my life trying to get it working.

    I've read the guidance, I'm calling mootools and the hoverbox.js, I'm calling the inline javascript, I think I've defined the ids correctly.... nothing not even an error. There's blatantly something simple that I'm misunderstanding in the explanation or I've done wrong, but I can't see it.... Any ideas before I go insane... http://www.4comment.co.uk/hoverboxtest/
  8. Troy


    Groover - I would start by checking to make sure that the domready event is firing (throw an alert in there where you are initiating the hoverbox object). Other than that, it appears at first glance that you have everything set up correctly.
  9. Adam


    Hello,

    Is there a way to add an onMouseOver trigger to run the code to hide/unhide the box?



    I'm trying to implement this into an AJAX app and the addEvents aren't getting added to the newly loaded content.
  10. Adam


    This got filtered out of my last message but something like this:

    &lt; img id='1' src='imgs/more_details.gif' alt='' onMouseOver='ShowBox()' /&gt;
  11. Jonathan


    We are working on a new site.
    The new top menu is using your hover box. as you hover over the top itme the box drops down with more links.
    The problem we have is the window.addEvent('domready', function() dosn't if we add the options.

    Now the popup box works ok on the yoffset but the xoffset is miles off and different in firefox and IE. The further accross the menu bar to the left you go the worse it gets.

    Any ideas any one?

    Cheers
    Jonathan
  12. Troy


    Johnathan - If you trying to create a drop down menu, i would recommend using something like http://www.alistapart.com/articles/dropdowns/
  13. Arte


    I tried to test demo page in Opera 10. Not working
  14. Troy


    Thanks for letting me know. It's well overdue for an update.


Leave a Reply