Category: jQuery & jQuery UI
Dynamic jQuery UI ajax loaded dialog widgets
There were several goals to this code snippet.
- To stay with just the jQuery-UI Library and not have to add an additional library for the effect.
- To have code to the page that would add the dialog behavior to links of a specific class regardless of what page in the CMS the link was on.
- To load the dialog by ajax so that each link, assigned an ajax loading url specific to that link, would create a dialog with its own content (They don't all have to be the same even though generated from one snippet).
- And lastly, to be able to target a specific portion of the ajax loading page so the target could be a stand-alone page. In other words,only the relevant code would load in the dialog, but if javascript was disabled, a standalone page matching the site template would be loaded. By using the same page, the content did not necessarily have to either come from a specific ajax file which would require keeping the content of two files synced, not come from the database (though it could) requiring building a backend interface.
First, this requires jQuery and jQuery-ui to be loaded. I'm using a jQuery-ui library wih all the widgets included, so if that isn't what you're using, you'll need to add the dialog widget and any other libraries you would need for any effects you might add to the dialog.
I started with information I found on stackoverflow.com posted by Jek here.
The links for this code are formatted as <a href="/mypage.php" rel="My Title|/mypage.php #mydiv|500,300">My Link</a>
Here the rel property is structured as [title]|[target]|[w,h] where the target can point to a page or a portion of the page, and the w,h is optional. Also, the title can be left out and a default title used, but then only the target should be in the tag. That is easy to work around, but this works for me.
Here is the code.
$().ready(function() {
/*
// Create the dialog element and initialize its functionality.
// Rel is used to determine the target so portions of whole dosuments can be targeted.
*/
$('a.openDialog').live('click', function() {
var ajaxDialog = $('<div id="ajax-dialog" style="display:none;"></div>').appendTo('body');
ajaxDialog.dialog({
autoOpen: false,
modal: true,
close: function(event, ui)
{
$(this).dialog('destroy').remove();
}
});
/*
// Get and parse the rel attribute for a title, target, and optional width and height.
// If the title is left off, using this code, the width and height must be left off since
// it will assume that if any | symbol is included, the first item is the title.
*/
var rel = $(this).attr("rel");
if (rel.indexOf("|")) {
rel = rel.split("|");
var dialogTitle = rel[0];
var url = rel[1];
if (typeof(rel[2]) !== "undefined") {
var dim = rel[2].split(",");
}
} else {
var dialogTitle = "My Default Title";
var url = rel;
}
/*
// load remote content checking for whether a
// specified width and height are included above.
*/
$('#'+ajaxDialog.attr('id')).load(url, function() {
ajaxDialog.dialog("option","title",dialogTitle);
if (typeof(dim) !== "undefined") {
ajaxDialog.dialog("option","width",dim[0]);
ajaxDialog.dialog("option","height",dim[1]);
}
ajaxDialog.dialog("open");
});
//prevent the browser from following the link
return false;
});
With this sort of method, I can apply one set of code and make any link a unique ui dialog on the page. It is also allows me to have a complete page on the target in case javascript is disabled and only get the content I want for the dialog off that page. That makes it easier to update the information in only one place without having to use a database.
The next post will be doing the same on the ui tooltip which was a bit more challenging.
Dynamic ajax loaded jQuery UI Tooltips on click instead of hover
There were several goals to this code snippet.
- To stay with just the jQuery-UI Library and not have to add an additional library for the effect.
- To have code to the page that would add the tooltip behavior to links of a specific class regardless of what page in the CMS the link was on.
- To have the tooltips show by link rather than hover (just what I needed for this project).
- To load the tooltip by ajax so that each link, assigned an ajax loading url specific to that link, would create a tooltip with its own content (They don't all have to be the same even though generated from one snippet).
- And lastly, to be able to target a specific portion of the ajax loading page so the target could be a stand-alone page. In other words,only the relevant code would load in the dialog, but if javascript was disabled, a standalone page matching the site template would be loaded. By using the same page, the content did not necessarily have to either come from a specific ajax file which would require keeping the content of two files synced, not come from the database (though it could) requiring building a backend interface.
First, this requires jQuery and jQuery-ui to be loaded. I'm using a jQuery-ui library wih all the widgets included, so if that isn't what you're using, you'll need to add the tooltip widget and any other libraries you would need for any effects you might add to the dialog.
Unlike the post on doing something similar with the ui dialog widget, this code creates, on load, a hidden div for each tip that stays on the page. There were a number of issues with trying to create and destroy the tooltip content on demand, so I bypassed it. Thisshould make for a faster response anyway.
I found a lot of ideas for making the tooltip work on click rather than hover, and some for loading the tip with ajax, but none for doing both, and doing both created some challenges.
The posts I found helful were Sanmai's post on stackoverflow here, Wizzud's post in the jQuery forum here, and Elliot's post on stackoverfow here.
The links for this code are formatted as <a href="/mypage.php" rel="/mypage.php #mydiv">My Link</a>
Here the rel property is structured as the target content in mypage.php where the target can point to a page or a portion of the page.
Here is the code.
$().ready(function() {
/*
// Ajax Tooltip intitialization functions
// Initialize counter to create unique id's
*/
var i = 1;
// Go through each item
$("a.clickTip").each(function() {
// Add a unique id
$(this).prop("id","clickTip_"+i);
// Assign to a variable that can reach into sub-functions where $(this) cannot
// NOTE: it is important to do this after assigning the ID or
// multiple instances will fail by opening all instead of one instance
// in short, $(this) while specific within this code block, creates event bahaviors
// that are general to the class, so the last one would override the others
var elem = $(this);
// Get the ajax content url from the rel attribute.
// NOTE: This is done with load, so target a specific element on the target page
var url = $(this).attr("rel");
// Create a hidden on page container for the tip
var ajaxTip = $('<div id="ajax-tip_'+i+'" style="display:none;"></div>').appendTo('body');
// Load needs to refer to the ID rather than just ajaxTip.load(...
$('#'+ajaxTip.attr('id')).load(url);
// Initialize the tooltip to the id (NOT TO $(this))
elem.tooltip({
position: { my: "left-30 bottom-20", at: "left center" },
/*
// Make the items attach to the element
// (elem is specific $(this) is not since it is attached to the class
*/
items: elem,
content: function(callback) {
var data = ajaxTip.html();
callback(data)
}
});
// Control event responses
// Do not string these events as in elem.tooltip(...).off("mouseover"...).on(...
// It caused me "Cannot access method before initialization" errors
// Disable the mouseover event
elem.off( "mouseover" );
// Set the open method to the click event
elem.on( "click", function(e){
e.preventDefault();
elem.tooltip( "open" );
});
// Optional: Set the close method to a timeout on the mouseout event
elem.on("mouseout", function() {
setTimeout(function(){
elem.tooltip( "close" );
}, 5000);
});
// Increment the counter
i++;
});
});
With this sort of method, I can apply one set of code and make any link a unique ui tooltip on the page. It is also allows me to have a complete page on the target in case javascript is disabled and only get the content I want for the dialog off that page. That makes it easier to update the information in only one place without having to use a database. I plan to just use basic tooltip using the title tag for hover tooltips, and this code for click activated tooltips.