This was a quick project for the See Me homepage and my first reusable jQuery plugin. When hovering over a creative's profile a small tooltip style pop up appears. The popup currently adjusts along the x-axis so it is always in view but future updates will include vertical positional awareness and adjustments.

Update: A new design of the See Me home page has altered the style of the info popup to now hover over the users image.

sketch.jpg
popup-wf.png
popup-1.jpg
// User Info Popup
// by David Caputo 2013
//
// Options:
// fade: "true",
// fadeSpeed: '200',
// delayIn: '200',
// offset: 0
//

(function($) {

function InfoWidget(element, options){
this.$element = $(element);
this.options = options;
};

InfoWidget.prototype = {
show: function(){
var $infoBox = this.makeInfo();

$infoBox.remove().css({display: 'block', visibility: 'hidden', top: 0, left: 0, opacity: 0}).prependTo(document.body);

var pos = this.$element.offset();

pos.elWidth = this.$element[0].offsetWidth;
pos.elHeight = this.$element[0].offsetHeight;

pos.boxWidth = $infoBox[0].offsetWidth;

var boxLeft = pos.left - (pos.boxWidth/2 - pos.elWidth / 2);
var arrowMargin = -7;

// Check if the box will be off the screen and adjust it in 20px;
if(boxLeft<0){
boxLeft=20;
$infoBox.find('.info-box-arrow').css({'margin-left': 0, 'left': 20 });
} else if(pos.elWidth + pos.left +10 > $('html').width()){
boxLeft = $('html').width() - pos.boxWidth - 20;
$infoBox.find('.info-box-arrow').css({'margin-left':0, 'left': 'auto', 'right': 20});
}

// Final Position Above element
var finPos;
finPos = {top: pos.top-120+this.options.offset,left: boxLeft};

// Style/Position the box
$infoBox.css(finPos);

if(this.options.fade) {
$infoBox.css({visibility: 'visible'}).animate({opacity: 1, top: finPos.top+5 }, this.options.fadeSpeed);
} else {
$infoBox.css({visibility: 'visible'}).css({opacity: 1});
};

},

hide: function(){
this.makeInfo().stop().fadeOut(this.options.fadeSpeed, function(){
$(this).remove();
});
},

makeInfo: function(){
var profileTitle = $(this.$element[0]).data('profiletitle');
var profileImageSrc = $(this.$element[0]).data('profileimgsrc');
var location = $(this.$element[0]).data('location');
var viewCount = $(this.$element[0]).data('viewcount');
var supporterCount = $(this.$element[0]).data('supportercount');


// Check to see if there is an infoBox associated with this DOM element. If so return that element, if not create it.
if(!this.$infoBox){
this.$infoBox = $('<div class="info-box"><div>').html('<div class="info-box-arrow"></div>');
if(profileImageSrc != ''){
$('<div class="prof-img"><img style="width:90px;height:90px;" src="' + profileImageSrc + '"/></div>').appendTo(this.$infoBox);
}

var $innerInfoBox = $('<div class="info-box-inner"><h1 class="prof-name">' + profileTitle + '</h1><h2 class="prof-loc">' + location + '</h2></div>');
$profStats = $('<div class="prof-stats"></div>');

if (viewCount > 0){
$('<span id="views-num">' + viewCount + '</span> Views<div style="display: inline-block; height:10px; width: 20px"></div>').appendTo($profStats);
}
if (supporterCount > 0){
$('<span id="support-num">' + supporterCount + '</span> Supports</div>').appendTo($profStats);
}
$profStats.appendTo($innerInfoBox);
$innerInfoBox.appendTo(this.$infoBox);

}
return this.$infoBox;
}

};

$.fn.showInfo = function(options) {

var defaults = {
fade: "true",
fadeSpeed: '200',
delayIn: '200',
offset: 11
};

var options = $.extend(defaults, options);

function get(ele) {
var userInfo = $.data(ele, 'userInfo');
if(!userInfo) {
userInfo = new InfoWidget(ele, options);
$.data(ele, 'userInfo', userInfo);
}
return userInfo;
};

function enter() {
var userInfo = get(this);
userInfo.show();
};

function leave() {
var userInfo = get(this);
userInfo.hide();
};

// Run through all elements and assign data to them
this.each(function(){
get(this);
});

// Bind the actions
this.on('mouseenter', enter);
this.on('mouseleave', leave);
};

})(jQuery);