Reputation: 26281
I created a jQuery plugin which queries the server via ajax and displays a popup. I then wanted another one on a different page which returns some different data and displays it. The way I implemented it, the plugin would send data indicating what page it was on to the server, the server would get the data and send back the type of data, and the client would display it as appropriate for the given type of data.
My approach obviously has a lot to be desired. Instead, is it possible to make an abstract version of the plugin, and then extend it to for each particular application so it displays it correctly (i.e. get rid of the switch statement)? Also, how can I get away from using an id on the popup (i.e. #screenshot) so each can be styled individually? Thanks
ayb={};
$("a.screenshot").screenshotPreview();
function contact(data)
{
return '<dl><dt>Name:</dt><dd>'+data.firstname+' '+data.lastname+'</dd>'
+'<dt>Account:</dt><dd>'+data.account_name+'</dd>'
+'<dt>Name:</dt><dd>'+data.firstname+' '+data.lastname+'</dd>'
+((data.title)?'<dt>Title:</dt><dd>'+data.title+'</dd>':'')
+'<dt>User Name:</dt><dd>'+data.username+'</dd>'
+'<dt>Password:</dt><dd>'+data.password+'</dd>'
+'<dt>Communication Method:</dt><dd>'+data.communication_method+'</dd>'
+((data.email)?'<dt>Email:</dt><dd>'+data.email+'</dd>':'')
+((data.account_phone)?'<dt>Account Phone:</dt><dd>'+display_phone(data.account_phone)+'</dd>':'')
+((data.phone)?'<dt>Direct Phone:</dt><dd>'+display_phone(data.phone)+'</dd>':'')
+((data.mobile_phone)?'<dt>Mobile Phone:</dt><dd>'+display_phone(data.mobile_phone)+'</dd>':'')
+((data.account_fax)?'<dt>Account Fax:</dt><dd>'+display_phone(data.account_fax)+'</dd>':'')
+((data.fax)?'<dt>Direct Fax:</dt><dd>'+display_phone(data.fax)+'</dd>':'')
+((data.address || data.location)?'<dt>Address:</dt><dd>'+data.address+((data.address && data.location)?'<br>':'')+data.location+'</dd>':'')
+((data.email)?'<dt>Email:</dt><dd>'+data.email+'</dd>':'')
+'</dl>';
}
function account(data)
{
return '<dl><dt>Name:</dt><dd>'+data.name+'</dd>'
+((data.phone)?'<dt>Account Phone:</dt><dd>'+display_phone(data.phone)+'</dd>':'')
+((data.fax)?'<dt>Account Fax:</dt><dd>'+display_phone(data.fax)+'</dd>':'')
+((data.address || data.location)?'<dt>Address:</dt><dd>'+data.address+((data.address && data.location)?'<br>':'')+data.location+'</dd>':'')
+((data.vertical_markets)?'<dt>Primary Market:</dt><dd>'+data.vertical_markets+'</dd>':'')
+((data.priority)?'<dt>Priority:</dt><dd>'+data.priority+'</dd>':'')
+'</dl>';
}
function user(data)
{
return '<dl><dt>Name:</dt><dd>'+data.firstname+' '+data.lastname+'</dd>'
+'<dt>User Name:</dt><dd>'+data.username+'</dd>'
+((data.phone)?'<dt>Direct Phone:</dt><dd>'+display_phone(data.phone)+'</dd>':'')
+((data.mobile_phone)?'<dt>Mobile Phone:</dt><dd>'+display_phone(data.mobile_phone)+'</dd>':'')
+((data.fax)?'<dt>Direct Fax:</dt><dd>'+display_phone(data.fax)+'</dd>':'')
+((data.email)?'<dt>Email:</dt><dd>'+data.email+'</dd>':'')
+'</dl>';
}
function getUrlVars(href)
{
//Returns object based on variables in url. Used to send data to GET
var vars = {}, hash, hashes = href.slice(href.indexOf('?') + 1).split('&');
for(var i = 0; i < hashes.length; i++)
{
hash = hashes[i].split('=');
vars[hash[0]] = hash[1];
}
return vars;
}
(function( $ ){
$.fn.screenshotPreview = function() {
//Apply to links to get a preview of the link
//Config - Set popup's distance from the cursor
ayb.screenshot={};
ayb.screenshot.xOffset = 20;
ayb.screenshot.yOffset = 10;
ayb.screenshot.showing=false;
this.hover(function(e)
{
if(!ayb.screenshot.showing){
ayb.screenshot.title = this.title;this.title = "";//Prevent title from being displayed,and save for later to put back
var url=getUrlVars(this.href);
ayb.screenshot.timeoutID=window.setTimeout(function() {
ayb.screenshot.showing = true;
url.task="getPopup"; //specify task
ayb.screenshot.ajax=$.ajax({
url: 'index.php',
data: url,
success: function(data)
{
//Determine how to display returned data
switch (data.type)
{
case 'contact':var string=contact(data);break;
case 'account':var string=account(data);break;
case 'user':var string=user(data);break;
case 'project':var string=project(data);break;
default:var string='Error';
}
$("body").append('<div id="screenshot">'+((ayb.screenshot.title != '')?'<h3>'+ayb.screenshot.title+'</h3>':null)+string+"</div>");
$("#screenshot")
.css("top",(e.pageY - ayb.screenshot.yOffset) + "px")
.css("left",(e.pageX + ayb.screenshot.xOffset) + "px")
.fadeIn("fast");
},
dataType: 'json'
});
},250); //Wait 1/4 of a second before requesting data from server
}
},
function()
{
//When not hover
if (typeof ayb.screenshot.ajax == 'object') {ayb.screenshot.ajax.abort();}
window.clearTimeout(ayb.screenshot.timeoutID);
this.title = ayb.screenshot.title;
$("#screenshot").remove();
ayb.screenshot.showing = false;
});
this.mousemove(function(e)
{
$("#screenshot").css("top",(e.pageY - ayb.screenshot.yOffset) + "px").css("left",(e.pageX + ayb.screenshot.xOffset) + "px");
});
};
})( jQuery );
Upvotes: 0
Views: 135
Reputation: 171679
Several ideas that might help. First is using data-
attributes in the markup:
<a href="#" class="screenshot" data-type="user">User Link</a>
Next is creating a more generic template method. The use type can be taken from the html data-type
and by adding the class of same type ( or some other protocol related to type) you can have different css for different use cases
DEMO JS:
(function ($) {
var shotTemplate = function (data, type) {
this.shot = {
start: '<div id="screenshot" class="' + type + '">',
end: '</div>},'
};
this.user = function () {
/* not suggesting "data.type" protocol, was just simple for my demo*/
return '<div class="user_class">' + data.user + '</div>';
};
this.contact = function () {
return '<div class="contact_class">' + data.contact + '</div>';
};
this.account= function () {
return '<div class="account_class">' + data.account + '</div>';
};
return this.shot.start + this[type]() + this.shot.end;
};
$.fn.screenshotPreview = function () {
return this.each(function () {
var $el = $(this);
/* isolate screenshot to this instance*/
var $screenshot;
$el.hover(function () {
$.post(url,data,function( response){
$screenshot = $(shotTemplate(response, $el.data('type')));
$('body').append($screenshot);
});
}, function () {
$screenshot.remove();
})
});
};
})(jQuery);
CSS:
#screenshot.user{background:navy;color:white}
#screenshot.contact{background:#444;color:white}
DEMO: http://jsfiddle.net/wceDc/
I kept demo simple to allow focusing on concepts and not clutter code with positioning
Upvotes: 1