Getting Started So how do I install this thing!?

jQuery version support

qTip2 requires jQuery 1.6 and up, and is also compatible with the new jQuery 2.x releases

Note: Prior to the qTip 2.1 release, jQuery 1.9.x support was broken due to $.browser removal. Ensure you're using the latest release to fix these issues.

Image support

Optional: imagesLoaded plugin

If you plan on using qTip2 with complex content that contains images, make sure to grab and include the latest jquery.imagesLoaded release for buttery smooth positioning!

v2.1.x Note: the imagesLoaded plugin is included in the jquery.qtip.js in these releases, so you do not need to add it manually. However, this was moved into a separate plug in v2.2 and requires you include it manually, for dependency management purposes.

Static HTML page

I highly recommend that all non-essential (i.e. non-library) JavaScript includes be placed just before the end </body> tag, as this ensures the DOM is loaded before manipulation of it occurs, and the scripts don't block other resources. This isn't a requirement, simply an insiders tip!

<html>
<head>
<title>My site</title>

<!-- CSS file -->
<link type="text/css" rel="stylesheet" href="/path/to/jquery.qtip.css" />
</head>
<body>

<!-- jQuery FIRST i.e. before qTip (and all other scripts too usually) -->
<script type="text/javascript" src="/path/to/jquery.min.js"></script>

<!-- Include either the minifed or production version, NOT both!! -->
<script type="text/javascript" src="/path/to/jquery.qtip.js"></script>

<!-- Optional: imagesLoaded script to better support images inside your tooltips -->
<script type="text/javascript" src="/path/to/jquery.imagesloaded.pkg.min.js"></script>
</body>
</html>

Note: Make sure to include either the minified or the un-minified script, not both!
Note: Notice the jQuery library is included before qTip2 . This is absolutely essential for correct functioning of the plugin!

Wordpress

You'll need to use Wordpress's wp_enqeueue_script function to load qTip2 into your blog. Load up your current theme's file and locate your wp_head call. Insert this before it:

<?php
// Add the styles first, in the <head> (last parameter false, true = bottom of page!)
wp_enqueue_style('qtip', '/path/to/jquery.qtip.min.css', null, false, false);

// Using imagesLoaded? Do this.
wp_enqueue_script('imagesloaded', '/path/to/imagesloaded.min.js', null, false, true);
wp_enqueue_script('qtip', '/path/to/jquery.qtip.min.js', array('jquery', 'imagesloaded'), false, true);

// Not using imagesLoaded? :( Okay... then this.
wp_enqueue_script('qtip', '/path/to/jquery.qtip.min.js', array('jquery'), false, true);
?>

And walah! qTip2 and jQuery are now included properly on your blog, in the footer on the page template. I also recommend you include another script which contains your qtip() call:

<?php wp_enqueue_script('qtipCall', '/path/to/qtipcall.js', array('jquery', 'qtip'), false, true); ?>

Find more information here, here and here

Drupal (v6-7)

You can add the JavaScript and CSS files in a similar manor to the Wordpress isntructions above, via:

<?php
// JavaScript
drupal_add_js(drupal_get_path('theme', 'mytheme') . '/path/to/jquery.qtip.min.js'); // Within a theme
drupal_add_js(drupal_get_path('module', 'mymodule') . '/path/to/jquery.qtip.min.js'); // Within a module

// CSS Styles
drupal_add_css(drupal_get_path('theme', 'mytheme') . '/path/to/jquery.qtip.min.css'); // Within a theme
drupal_add_css(drupal_get_path('module', 'mymodule') . '/path/to/jquery.qtip.min.css'); // Within a module
?>

For more information and a lengthy guide see this Drupal Wiki article

Joomla

Again, in a similar manor to the other frameworks, using Joomla's builtin API calls we can do:

<?php
$document = JFactory::getDocument();
$document->addScript('/path/to/jquery.qtip.min.js'); // Change the path
$document->addStyleSheet('/path/to/jquery.qtip.min.css'); // Change the path
?>

For more information see this Joomla Wiki article

Bower

To install qTip2 using Twitter's Bower package mananagement, simply type...

bower install qTip2 // lowercase!

...into the terminal, where it will be installed into the bower_components/ directory.

Nuget

To install qTip2 using Nuget, the package manager for the Microsoft development platform, simply type...

Install-Package qTip2 

...into the terminal, when residing within your project directory.

AMD / RequireJS

qTip2 is also a valid AMD module that works with RequireJS:

  1. Install qTip2 using Bower or download directly from cnjs
  2. Update your RequireJS paths config so it can find those modules
    requirejs.config({
     paths: {
         "imagesLoaded": "/path/to/imagesLoaded.pkg.min", // Optional "dependancy"
         "qTip2 ": "/path/to/jquery.qtip.min"
     }
    });

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.tooltip.html('Loading...');

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

api.elements.tooltip.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.

Styling guide Learn how to customize your tooltips' appearance

HTML structure

Below is the auto generated HTML of tooltip. We can use each elements classes to target them using CSS and manipulate the default styles of the library and tooltips.

<!-- ARIA properties are detailed on the second line, which are applied for accessibility purposes -->
<div id="qtip-{id}" class="qtip qtip-default qtip-pos-rc" style="z-index: 15001;" tracking="false"
        role="alert" aria-live="polite" aria-atomic="false" aria-describedby="qtip-0-content">

    <!-- content.title must be set for this to be generated -->
    <div class="qtip-titlebar">
         <!-- Only generated when content.button is set to true -->
         <!-- If content.title is unset, then this will be appended to the .qtip element, see below -->
        <a class="qtip-close qtip-icon" title="{content.button}" aria-label="{content.button}" role="button"> 
            <span class="ui-icon ui-icon-close">&cross;</span>
        </a>

        <!-- Houses the tooltip title -->
        <div id="qtip-{id}-title" class="qtip-title">{content.title}</div>
    </div>

    <!-- Only generated when content.button is set to true AND content.title is false -->
    <a class="qtip-close qtip-icon" title="{content.button}" aria-label="{content.button}" role="button"> 
        <span class="ui-icon ui-icon-close">&cross;</span>
    </a>

    <!-- Houses the tooltip content -->
    <div id="qtip-{id}-content" class="qtip-content ui-widget-content" aria-atomic="true">
        {content.text}
    </div>
</div>

Please do not add this manually to your page, it is auto-generated by the library for you.

Built-in styles

qTip2 comes with a variety of bog-standard CSS2.1, and rather more elegant CSS3 styles. Depending which you included in your particular build, you can use them throughout your application. Heres a listing:

/* Basic styles */
.qtip-light{} /* Light coloured style */
.qtip-dark{} /* Alternative dark style */
.qtip-cream{} /* Cream-esque style, similar to the default */
.qtip-red{} /* Alert-ful red style */
.qtip-green{} /* Positive green style */
.qtip-blue{} /* Informative blue style */

/* CSS3 styles */
.qtip-rounded{} /* CSS3 border-radius class for applying rounded corners to your tooltips */
.qtip-shadow{} /* CSS3 box-shadow class for applying shadows to your tooltips */
.qtip-bootstrap{} /* Twitter Bootstrap style */
.qtip-youtube{} /* Google's new YouTube style  */
.qtip-tipsy{} /* Minimalist Tipsy style */
.qtip-tipped{} /* Tipped libraries "Blue" style */
.qtip-jtools{} /* jTools tooltip style */
.qtip-cluetip{} /* Good ole' ClueTip style */

You can see a live demonstration of these styles on the main website

Applying custom classes

You can apply custom classes the the main .qtip element by setting the style.classes option

$('.selector').qtip({
    style: { classes: 'myCustomClass' }
});
.myCustomClass{
    border-color: rgb(0,190,0);
    background-color: #ddd;
}

If you wish to style elements such as the .qtip-content element, simply use descendant selectors like so:

.myCustomClass .qtip-content{
    font-size: 12px;
}

Changing tooltip dimensions

Setting the width and height of a tooltip can be done in two ways:

/* Via CSS, to be applied ot multiple tooltips */
.myCustomClass{
    width: 100px;
    height: 200px;
}

… or specifying it in the style object for specific tooltips

$('.selector').qtip({
    style: {
        classes: 'myCustomClass',
        width: 500, // Overrides width set by CSS (but no max-width!)
        height: 200 // Overrides height set by CSS (but no max-height!)
    }
})

However, please note that the .qtip class has a default max-width: 280px; style that will limit the width!

Using Themeroller classes

qTip2 has full support for jQuery UI Themeroller styles, and is controlled on a per-tooltip basis (disabled by default) using the style.widget property.

$('.selector').qtip({
    content: 'I won\'t be styled by the pages Themeroller styles',
    style: {
        widget: true, // Use the jQuery UI widget classes
        def: false // Remove the default styling (usually a good idea, see below)
    }
})

It's also often beneficial when using Themeroller styles to prevent the default tooltip styles being applied, which can be done by setting the style.def option to false.

Events

Multiple callbacks

Unlike the 1.x releases, qTip2 now supports multiple callbacks for your events, so you can have lots of things triggered from a single tooltip event. Let's dive in and look at an example:

$('.selector').qtip({
    content: 'Multiple callbacks... mmm...',
    events: {
        show: function(event, api) { $('.selector').addClass('show'); },
        render: function(event, api) {
            // Grab the tooltip element from the API
            var tooltip = api.elements.tooltip

            // ...and here's the extra event binds
            tooltip.bind('tooltipshow', function(event, api) {
                $('.selector').removeClass('active');
            })
        }
    }
});

You'll notice that we're actually using two event callbacks, show and render. The events.show option sets the first callback, and the render option lets us assign multiple other callbacks using a regular old .bind() method, once we know the tooltip has rendered.

You can also bind callbacks outside the qTip2 call, again using a regular bind. Though take note that this only works if pre-rendering is enabled, as you can only bind events to elements that you know exist in the DOM when it's bound. Here's the example:

$('.selector').qtip({
    id: 'multibind', // Give it an ID of 'qtip-multibind' for easy reference
    prerender: true, // Pre-render tooltip HTML on document.ready
    content: 'Multiple callbacks... mmm...',
    events: {
        show: function(event, api) {
            $('.selector').addClass('show');
        }
    }
});

// And here's our extra non-qTip-call bind, using our assigned class as a selector
$('#qtip-multibind').bind('tooltipshow', function() {
    $('.selector').removeClass('active');
});

Stopping events

Stopping the event before its outcome occurs… possible? Sure! Just like regular events assigned using .bind() or .delegate(), using the event.preventDefault() method will cause the event to be stopped e.g. not proceed or 'bubble'. This is similar to the old 1.x before callbacks. Example:

$('.selector').qtip({
    content: 'Multiple callbacks... mmm...',
    events: {
        show: function(event, api) {
            // Only show the tooltip if say... an element is also visible
            if($('.selector').is(':hidden')) {
                // IE might throw an error calling preventDefault(), so use a try/catch block.
                try { event.preventDefault(); } catch(e) {}
            }
        }
    }
});

Right-clicks

Now that we know how to stop events, we can pull off some pretty nice implementations. Like what you ask? Oh I don't know... maybe our own context menu?

$('.selector').qtip({
    content: $('#contextMenu'), // Use a pre-formatted element for the content
    position: {
        target: 'mouse', // Position it where the click was...
        adjust: { mouse: false } // ...but don't follow the mouse
    },
    show: 'mousedown', // Can't use click event for this, sorry!
    events: {
        show: function(event, api) {
            /*
             * event.originalEvent contains the event that caused the callback to be fired.
             * event.originalEvent.button tells us which button was clicked e.g. 1= left, 2 = right;
             */
            if(event.originalEvent.button !== 2) {
                // IE might throw an error calling preventDefault(), so use a try/catch block.
                try { event.preventDefault(); } catch(e) {}
            }
        }
    }
})
// Little snippet that stops the regular right-click menu from appearing
.bind('contextmenu', function(){ return false; });

Now you've seen qTip2 isn't just limited to creating regular old tooltips, but can be used in some pretty interesting ways. The worlds your oyster… so go out and play! But make sure to write about it when you make something cool, and tell us where!

Delegation .on() / live() / .delegate()

There are plenty of tooltip scripts out there that support jQuery's new to 1.4 .live() / .delegate() / .on… so why should qTip2 be any exception? Well thankfully for you it isn't! To understand how to use these special event delegation techniques, it's best to simply dive into a code example and explain exactly what's happening:

// We'll encapsulate our .qtip() call in your .on() handler method
$(document).on('mouseover', '.selector', function(event) {
    // Bind the qTip within the event handler
    $(this).qtip({
        overwrite: false, // Make sure the tooltip won't be overridden once created
        content: 'I get bound to all my selector elements, past, present and future!',
        show: {
            event: event.type, // Use the same show event as the one that triggered the event handler
            ready: true // Show the tooltip as soon as it's bound, vital so it shows up the first time you hover!
        }
    }, event); // Pass through our original event to qTip
})

// Store our title attribute in 'oldtitle' attribute instead
.each(function(i) {
    $.attr(this, 'oldtitle', $.attr(this, 'title'));
    this.removeAttribute('title');
});

Ok so let's break down the code in its constituent parts...

Event handler

$(document).on('mouseover', '.selector', function(event) { });

This part tells jQuery to run the defined function on all elements matched by the .selector string, past present and future! This allows us to easily add tooltips to certain elements on a page, even when updating the DOM and adding new elements.

.qtip call

Now we have the .qtip() method being called via our .on() handler, let's take a look at the options required for this to work:

$(this).qtip({
    overwrite: false, // Make sure the tooltip won't be overridden once created
    content: 'I get bound to all my selector elements, past, present and future!',
    show: {
        event: event.type, // Use the same show event as triggered event handler
        ready: true // Show the tooltip immediately upon creation
    }
}, event); // Pass through our live event to qTip

To make sure our tooltips aren't re-created when the DOM is updated, we make sure our overwrite option is set to false. This is especially vital when using the $.ajax functionality. Next we setup our show.event to use the same event.type as the original .on() handler. This isn't required, but it's shorter than writing out our 'mouseover' string twice, and it minifies better!

Also, show.ready option should be true, which causes the tooltip to render and show as soon as the .qtip() method is called. This is vital, as otherwise the qTip will only show up on subsequent event triggers, not the initial one! Also, remember to pass the event object as the second .qtip() parameter, otherwise certain positioning stuff won't work as expected!

Remove title

Finally, we remove the title attribute and store it in the oldtitle attribute, so we don't get any of the default browser tooltips showing up.

// Store our title attribute in 'oldtitle' attribute instead
.each(function(i) {
    $.attr(this, 'oldtitle', $.attr(this, 'title'));
    this.removeAttribute('title');
});

Integration Learn how to use qTip2 with other plugins

Plugins inside qTip2 

qTip2 uses a method known as "lazy-loading", which basically means that it only creates your tooltips on demand, not on page load (unless prerender is true!). This means the tooltip HTML, and therefore the contents of the tooltip, won't be available on $(document).ready(), so .bind() calls won't work! So...

If you're wanting to inject something dynamic into the tooltip content, say for example, add some fancybox links inside it, you'll need to nest your other plugin(s) initialisation within the render event callback

$('.selector').qtip({
    content: $('.selector') // The content you are putting in your tooltip, with the other plugin needs access to,
    events: {
        render: function() {
            // Grab the content
            var content = api.elements.content;

            // Now it's rendered, we can...
            content.otherPlugin(); // ...Call our other plugins to act on its contents
            $('a', content).otherPlugin(); // ...or a subset of its contents!
        }
    }
});

qTip2 inside plugins

What about tooltips which use content within another plugin? I can't give exact details, because every plugin provides (or should anyway!) different callbacks, but basically you'll normally need to find an equivalent to qTip2 's render callback, and nest your qTip call within it.

Isotope

Isotope implements an old version of the imagesLoaded plugin, which causes problems with qTip2 . To solve this, simply re-include the latest imagesLoaded script after the isotope script.

<script src="/path/to/isotope.js"></script>
<script src="/path/to/jquery.qTip2 .js"></script>
<script src="/path/to/imagesloaded.js"></script> <!-- Must be AFTER isotope -->

jQuery Validation plugin

$('form').validate({
    errorPlacement: function(error, element) {
        // qTip call
        $(element).not('.valid').qtip();
    },
    success: function(error) {
        // Hide tooltips on valid elements
        setTimeout(function() {
            myForm.find('.valid').qtip('hide');
        }, 1);
    }
});

jMonthCalendar

$.jMonthCalendar.Initialize(
{
    onEventBlockClick: function(event)
    {
        // qTip call
        $(this).qtip();
    }
}
, events);

Custom build Adding and removing features using git

What you need

In order to build qTip2 , you need to have Node.js 0.10.0 or later and grunt / grunt-cli 0.5 or later.

Installing Node.js

Head over to http://nodejs.org/ to grab the OS-specific installer for Node.js and the Node Package Manager.

Installing grunt

  1. Test that grunt-cli is installed globally by running grunt --version at the command-line.
  2. If grunt isn't installed globally, run npm install -g grunt-cli to install the latest version. You may need to run it using sudo.
  3. From the root directory of this project, run npm install to install the needed dependancies.

Checkout dependencies (git submodules)

  1. cd into the checked-out qTip2 directory
  2. Run git submodule init
  3. Then git submodule update
  4. Done!

Building qTip2 

First, clone a copy of the main qTip2 git repo by running

git clone git://github.com/Craga89/qTip2.git

Then, in the main directory of the distribution (the one that this file is in), type the following to build qTip2  and its accompanying CSS:

grunt

You can also create each individually using these commands:

grunt clean    # Clean up the dist/ directory
grunt basic    # Build qTip2 with no plugins included
grunt css     # Build CSS files
grunt all    # Build qTip2 twice, with no plugins and all plugins

To build and test the source code against JSHint/CSSLint, type this:

grunt dev

Finally, you can remove all the built files using the command:

grunt clean

Choosing features

By default qTip2  is built with all plugins enabled. You can see an example of this in the dist file. If you want more control over what plugins are included, you can do so by adding some extra parameters to your build commands.

For example, if you plan on using only the tips plugin, you'd specify the plugins variable as so:

grunt --plugins="tips" [command]

Notice the only thing that was added was the PLUGINS parameter. This tells the compiler which files to include in the final qTip2  build. You can specify multiple plugins by separating them with a space:

grunt --plugins="tips ajax viewport" [command]

By default all plugins are included in the build, so the regular [grunt all] command is actually equivilent to:

grunt --plugins="ajax viewport tips imagemap svg modal bgiframe" [command]