This plugin displays a tooltip popup with the data obtained via Ajax. I am sure there are better ones out there, but my objective is to learn how to correctly build a plugin, not find the best one available. I would appreciate any comments, suggestions, criticism from a best practices and design pattern usage perspective.
A live demo is located here.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
<title>screenshot</title>
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<script src="jquery.ajaxTip.js" type="text/javascript"></script>
<style type="text/css">
.myElement{margin:100px;}
.ajaxToolActive{color:blue;}
.myAjaxTip {
border:1px solid #CECECE;
background:white;
padding:10px;
display:none;
color:black;
font-size:11px;-moz-border-radius:4px;
box-shadow: 3px 1px 6px #505050;
-khtml-border-radius:4px;
-webkit-border-radius:4px;
border-radius:4px;
}
</style>
<script type="text/javascript">
$(function(){
$('.myElement').ajaxTip({
display: function(d){return '<p>'+d.name+'</p><p>'+d.address+'</p><p>'+d.city+', '+d.state+'</p>';},
getData:function(){return {id:this.data('id')}},
'class':'myAjaxTip'
});
$('.destroy').click(function(){$('.myElement').ajaxTip('destroy');});
});
</script>
</head>
<body>
<p class="myElement" data-id="1" title="ajaxTip Popup">John Doe</p>
<p class="myElement" data-id="2" title="ajaxTip Popup">Jane Doe</p>
<p class="myElement" data-id="3" title="ajaxTip Popup">Baby Doe</p>
<p class="destroy">Destroy</p>
</body>
</html>
/*
* jQuery ajaxTip
* Copyright 2013 Michael Reed
* Dual licensed under the MIT and GPL licenses.
*/
(function( $ ){
var methods = {
init : function( options ) {
// Create some defaults, extending them with any options that were provided
var settings = $.extend({
'url' : 'getAjaxTip.php', //To include extra data sent to the server, included it in the url
'class' : '', //Class to be added to tooltip (along with class standardAjaxTip)
'mouseMove': true, //Whether to move tooltip with mouse
'speed' : 'fast', //fadeIn speed
'delay' : 250, //milliseconds to delay before requesting data from server
'xOffset' : 20,
'yOffset' : 10,
'dataType' : 'json', //Returned data. Options are json, text, etc
'getData' : function(){return {}}, //Use to set additional data to the server
'display' : function(data){ //User function must include function(data) {... return string}
var string='';
for (var key in data) {string+='<p>'+data[key]+'</p>';}
return string;
}
}, options || {}); //Just in case user doesn't provide options
return this.each(function(){
var showing,title,timeoutID,ajax,$t=$(this).wrapInner('<span />'),ajaxTip;
$t.children('span').hover(function(e) {
if(!showing){
title = $t.attr('title');$t.attr('title','');//Prevent title from being displayed,and save for later to put back
timeoutID=window.setTimeout(function() {
ajax=$.get( settings.url,settings.getData.call($t),function(data){
ajaxTip=$('<div />')
.addClass('standardAjaxTip '+settings.class)
.html(((title != '')?'<h3>'+title+'</h3>':'')+settings.display(data))
.css("top",(e.pageY - settings.yOffset) + "px")
.css("left",(e.pageX + settings.xOffset) + "px")
.css("position","absolute")
.appendTo('body').fadeIn(settings.speed);
showing = true;
$t.addClass('ajaxToolActive');
}, settings.dataType);
},settings.delay); //Delay before requesting data from server
}
},
function()
{
//When not hover
if (typeof ajax == 'object') {ajax.abort();}
window.clearTimeout(timeoutID);
$t.attr('title',title);
$t.removeClass('ajaxToolActive');
if(showing){ajaxTip.remove();}
showing = false;
});
$t.mousemove(function(e) {
if(settings.mouseMove && showing) {ajaxTip.css("top",(e.pageY - settings.yOffset) + "px").css("left",(e.pageX + settings.xOffset) + "px");}
});
});
},
//Add additional methods as needed
destroy : function() {
//console.log('destroy');
return this.each(function(){
var $e = $(this);
$e.html($e.children('span').html());
})
},
};
$.fn.ajaxTip = function(method) {
if ( methods[method] ) {
return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.ajaxTip' );
}
};
})( jQuery );