Content Guide - qTip2/qTip2 GitHub Wiki

Content guide Text? HTML? Learn how to use the different content types

qTip2 supports the use of regular old browser text, as well as complex HTML, but what are the best ways of actually providing qTip2 with the content? Element attributes? Hidden text? It really depends upon your specific scenario, but here's some basic examples to get you started

Simple text

JavaScript String

If you just want a common piece of text shared between all your tooltips, you can supply qTip2 directly with a JavaScript String

$('a').qtip({ // Grab some elements to apply the tooltip to
	content: {
		text: 'My common piece of text here'
	}
})

title attribute

If you plan on using qTip2 as simply a very thin replacement of the browser tooltips, the title attribute is a great way to do so. It's standards compliant, it's the expected place for tooltip text, and the plugin will automaically look there for its content if none is given inside your .qtip({ ... }) config object!

$('[title]').qtip(); // Grab all elements with a title attribute, and apply qTip!
$('[title!=""]').qtip(); // A bit better. Grab elements with a title attribute that isn't blank.

This is the simplest method of using qTip2, as it requires very little setup and works to replace existing, native tooltips auto-magically!

custom attribute

If for some reason you can't use the title attribute, or you'd like to use a different attribute for your tooltip text, then you can easily tell qTip2 not to look in the title attribute by default, by setting the content.attr config property. For example, say we're using a custom data- attribute named data-tooltip:

$('[data-tooltip!=""]').qtip({ // Grab all elements with a non-blank data-tooltip attr.
	content: {
		attr: 'data-tooltip' // Tell qTip2 to look inside this attr for its content
	}
})

A note on "this" variable

For those of you new to JavaScript/jQuery land, we'll take a small side-track here to describe a unique property of JavaScript: the "this" variable. Feel free to skip this is you're already familiar with it.

This this variable in JavaScript is scope-dependant, meaning its value with change depending upon where abouts you access it within your code. For example, accessing the this keyword within the "global" scope i.e. outside any functions/scope, it will refer to the window element.

Here's a quick example of how "this" can change, depending upon where it's accessed:

// This will print out the value of "this" for us
function log() { console.log(this); };

log(); // Will print out the "window" (log function has no set scope) 
log.call([ 1 ]) // Will print out the "[ 1 ]" array
log.apply({ foo: "bar" }); // Will print out the "{ foo:"bar" }" object

Almost all of the jQuery methods which take a function as their parameter also set the value of "this" to refer to the element itself (or each element, if the jQuery object contains more than one). For example:

$('a').each(function() { // Grab all "<a>" elements, and for each...
	log(this); // ...print out "this", which now refers to each <a> DOM element 
});

$('[title]').qtip({ // Grab all elements with a title attribute
	content: {
		text: $(this).next() // Won't work, because "this" is the window element!
	}
});

$('[title]').each(function() { // Grab all elements with a title attribute,and set "this"
	$(this).qtip({ // 
		content: {
			text: $(this).next() // WILL work, because .each() sets "this" to refer to each element
		}
	});
});

HTML

A hidden element

For complex HTML content where you require the tooltip content to be printed out alongside the element that will be displaying the tooltip, the hidden element approach is best suited. When printing out your HTML, either via some server-side script like PHP or Python, or via hand in a text editor, put the tooltip contents within a <div> element located directly next to the element which requires the tooltip. For example:

<div class="hasTooltip">Hover me to see a tooltip</div>
<div class="hidden"> <!-- This class should hide the element, change it if needed -->
	<p><b>Complex HTML</b> for your tooltip <i>here</i>!</p>
</div>

It's important that the elements be directly next to eachother in the DOM otherwise this approach won't work because of the nature of the jQuery .next() method we'll be using! Once you've got the HTML set up as described above, we can setup our qTip's like so:

// Grab all elements with the class "hasTooltip"
$('.hasTooltip').each(function() { // Notice the .each() loop, discussed below
	$(this).qtip({
		content: {
			text: $(this).next('div') // Use the "div" element next to this for the content
		}
	});
});

XMLHTTPRequest (AJAX)

qTip 2.1 and above only! For users of older releases, see the AJAX plugin documentation.

For situations where you'd like to load in content from an external page, jQuery's Deferred Objects can be used in conjunction with the .ajax() method. We'll encapsulate the .ajax() call in an anonymous function, preventing immediate retrieval of the content until the tooltip has first been activated by the user. Upon retrieval (or error) we set the new content using the .set() API method, updating the tooltip and ensuring the request is only made once.

$('[data-url]').qtip({
	content: {
		text: function(event, api) {
			$.ajax({
				url: element.data('url') // Use data-url attribute for the URL
			})
			.then(function(content) {
				// Set the tooltip content upon successful retrieval
				api.set('content.text', content);
			}, function(xhr, status, error) {
				// Upon failure... set the tooltip content to the status and error value
				api.set('content.text', status + ': ' + error);
			});

			return 'Loading...'; // Set some initial text
		}
	}
});

Grab specific element(s) on another page

You can easily grab specific portions of another page by slightly altering the first api.set() call above, for example:

// Append the parsed HTML of the retrieved page to a dummy <div/>, and find all <h1> elements
var elements = $("<div />").append( $.parseHTML(content) ).find('h1');

// Set the content of the tooltip to the selected element(s)
api.set('content.text', elements);

Grab content continuously Update the content each time the tooltip is shown

If you'd like the tooltip to continually retrieve the URL's contents upon each successive show event, you can slightly alter the signature of the anonymous function, as below.

$('[data-url]').qtip({
	content: {
		text: function(event, api) {
			// This time, we return the deferred object, not a 'Loading...' message.
			return $.ajax({
				url: element.data('url') // Use data-url attribute for the URL
			})
			.then(function(content) {
				// Return the content instead of using .set(). If you're wanting to select
				// specific elements, see ther above section and adapt the `api.set` call
				// into a `return elements` statement!
				return content
			}, function(xhr, status, error) {
				// Errors aren't handled by the library automatically, so
				// you'll need to call .set() upon failure, just as before.
				api.set('content.text', status + ': ' + error);
			});
		}
	}
});

"Loading" text / spinners

You can also add a "Loading..." message or similar by pre-pending this to the above function:

api.elements.content.html('Loading...');

Or if you want a fancy spinner images or some sort...

api.elements.content.html('<img src="/path/to/spinner.gif" alt="Loading..."/>');

JSON

Nowadays the preferred method to return data from an AJAX request is via JSON, or JavaScript Object Notation. This is basically a fancy way of saying a JavaScript object.

Many popular server-side languages such as Ruby and PHP provide ways of encoding their native data structures into JSON syntax. Once you have your JSON being spat out correctly (example below), take a look at how to retrieve and use the JSON using qTip2:

/* JSON string returned by the server */
{
	"person": {
		"firstName": "Craig",
		"lastName": "Thompson",
		"gender": "Male",
		"dob": "14/09/19??",
		"country": "United Kingdom"
	},
	"job": {
		"title": "Web Developer",
		"company": "craigsworks",
		"since": 2007
	},
	"specialities": [
		"JavaScript", "jQuery", "CSS",
		"(X)HTML", "PHP", "MySQL"
	]
}
/* qTip2 call below will grab this JSON and use the firstName as the content */
$('.selector').qtip({
	content: {
		text: function(event, api) {
			$.ajax({
				url: '/path/to/json/output', // URL to the JSON file
				type: 'GET', // POST or GET
				dataType: 'json', // Tell it we're retrieving JSON
				data: {
					id: $(this).attr('id') // Pass through the ID of the current element matched by '.selector'
				},
			})
			.then(function(data) {
				/* Process the retrieved JSON object
				 *    Retrieve a specific attribute from our parsed
				 *    JSON string and set the tooltip content.
				 */
				var content = 'My name is ' + data.person.firstName;

				// Now we set the content manually (required!)
				api.set('content.text', content);
			}, function(xhr, status, error) {
				// Upon failure... set the tooltip content to the status and error value
				api.set('content.text', status + ': ' + error);
			});

			return 'Loading...', // Set some initial loading text
		}
	}
});

As you can see, processing the data is very simple. We take the parsed JSON string returned from the server, use its attributes to create the new content of the tooltip, and call the API's set method to replace the tooltip contents with it. Easy peasy!

Note: Unfortunately, the dataFilter callback cannot be used to filter the JSON object like in the HTML example above, only the unparsed JSON string.

⚠️ **GitHub.com Fallback** ⚠️