Bootstrap Tour Extended

Powerful JavaScript Tour library built for highly dynamic applications (a.k.a SaaS/RIA)

Bootstrap Tour Extended is a fork of Bootstrap Tour by sorich87. I forked it because it was not enough powerful to be useful as a tour library for my own products Bringr and Redsmin.

I wanted a persistant, clean, evented, deferred based Tour library with optional overlay support.

Online app Tour services could not offer (from what I saw) this depth of customization.

Bootstrap Tour Extended allows developers to build quickly and easily extremely configurable product tours using Twitter Bootstrap Popovers.

Some Tour global parameters can be strings or functions because sometimes the thing you want to expose does not exist when the Tour start.

Each #defaults.step parameters specified through new Tour([options]) can be overriden at the step level with tour.addStep([options]).

The default template can be completely replaced at the Tour level or even for a single step. It's a function(step) -> string, so underscore _.template(), jQuery $.tmpl() etc... are supported even if they are not Bootstrap Tour Extended dependencies.

See the demo from the original version by sorich87

I accept pull-requests!

In your web page:

<div id="a"></div><hr><div id="b"></div>

<script src="jquery.js"></script>
<script src="bootstrap.tooltip.js"></script>
<script src="bootstrap.popover.js"></script>
<script src="bootstrap-tour.js"></script>

<script type="text/javascript">
// Initialize the tour
var tour = new Tour({
  name:"myTour",
  persistence:"Memory",
  
  /**
   * Configure step wide parameters
   */
  step:{
    /**
     * Css class to add to the .popover element
     * @description Note: if `addClass` is defined at the step level.
     *              The two defined `addClass` will be taken into account in the popover
     * @type {String}
     */
    addClass:'myPopover',
    
    /**
     * Step wide title function can be defined (and even overriden at each step level)
     * @type {String, Function(step)}
     */
    title: function(step){return "step "+step.index;},
    
    /**
     * Default step content
     * @type {String | Function(step)}
     */
    content: "Default content"
  }
  
  /**
   * etc... See #defaults
   */
});

/**
 * Add a step
 */
tour
  .addStep({
    /**
     * {jQuery | Css Selector | Function} HTML element on which the step popover will be shown
     * @type {String}
     */
    element:   "#a",   
    
    /**
     * {String} Popover position - top | bottom | left | right.
     * @type {String}
     */
    placement: "bottom",
    
    /**
     * Popover title
     * @type {String | Function}
     */
    title:     "Hello world!"
    
    /**
     * etc... See #stepDefaults
     */
  });
  
/**
 * Oh yes, addStep/on/off/one/trigger are chainable
 */
tour
  .addStep({
    /**
     * #c does not exist yet but will be created by the following "show" event handler
     * @type {String}
     */
    element: "#c",
    
    /**
     * This popover will have the css class .bootstrap-tour.myTour-step1.myPopover.myowncssclass
     * @type {String}
     */
    addClass: "myowncssclass" 
  })
  .on("show:step1", function(e){
    // Deferred support for asynchronous operation
    var def = $.Deferred();
    
    // Tell Bootstrap Tour to wait for this promise to resolve before displaying the step
    // Note: in the case of multiple event handler, Bootstrap Tour will wait that all promise are resolved
    // before showing the step
    // Note2: e.setPromise() is optional, if no promises were specified the step will be immediately displayed.
    e.setPromise(def.promise());
    
    // "show" is the only event that does not have a "e.element" attribute
    // simply because the "show" event handler can wait, if necessary, for this element to be created.
    setTimeout(function(){
      $('<div>',{id:"c"}).appendTo("body");
      def.resolve();
    }, 1000);
  });
  
  
tour
  .on("show", function(e){
    console.log("Trying to show step", e.step.index);
  })
  .on("shown", function(e){
    console.log("Step", e.step.index, "shown");
  })
  .on("shown:step0", console.log.bind(console, "First step is displayed"))
  .on("hide", function(e){
    console.log("Hidding step", e.step.index);
  })
  .on("hidden:step1", function(e){
    console.log("Step", 
        e.step.index, 
        "is hidden, this action was triggered by", 
        e.trigger, 
        "the resolved step element was", 
        e.element);
  })
  .on("hidden", function(e){
    console.log("Step", e.step.index, "is now hidden");
  })
  .on("end", console.log.bind(console, "Tour ended"));
  
tour.on("skip", function(e){
  console.log("Bootstrap Tour is skipping step", 
    e.step.index,
    "because this step element",
    e.step.element,
    "was neither found nor visible.");
  // Thus this event handler will never be called
});

// Start the tour
tour.start();

// One more thing, .start(), .next(), .prev() and .end() all return promises!
</script>

Tour

function
Tour() -> Tour

Option name Type Description
options Object An optional option object (see #defaults)

Create a tour

dispose

method
Tour.prototype.dispose()

Remove the Tour

addStep

method
Tour.prototype.addStep() -> Tour

Option name Type Description
step Object An optional object that describe the step (see #stepDefaults)

Add a step to the tour

start

method
Tour.prototype.start() -> Promise

Option name Type Description
force Boolean If force is set to `true` the tour will be forced to start

Start tour from current step

gotoStep

method
Tour.prototype.gotoStep() -> Deferred

Option name Type Description
index Number Step index

Goto a step by its index

on

method
Tour.prototype.on() -> Tour

Option name Type Description
event String A string containing one Bootstrap-tour event types, it can be "hide", "hidden", "show", "shown" or "skip". Each event can have a `:step{index}` path appended. For instance the event "shown:step0" will be triggered when the first step will be shown on screen.

Attach an event handler function for one event.

one

method
Tour.prototype.one() -> Tour

Option name Type Description
name String A string containing one Bootstrap-tour event types, such as "hide", "hidden", "show", "shown" or "skip".

Attach a handler to an event. The handler is executed at most once.

off

method
Tour.prototype.off() -> Tour

Option name Type Description
event String Event name

Remove an event handler.

trigger

method
Tour.prototype.trigger() -> Tour

Option name Type Description
name String Event name (e.g. "show", "shown", "hide", "hidden", "skip")

Trigger an event on Tour

next

method
Tour.prototype.next() -> Promise

Option name Type Description
(optional) Object Event object

Hide current step and show next step

prev

method
Tour.prototype.prev() -> Promise

Option name Type Description
(optional) Object Event object

Hide current step and show previous step

end

method
Tour.prototype.end() -> Promise

Option name Type Description
(optional) String trigger

End the tour

ended

method
Tour.prototype.ended() -> Boolean

Verify if tour is enabled

restart

method
Tour.prototype.restart() -> Promise

Restart the tour

debugMode

method
Tour.prototype.debugMode() -> Tour

Option name Type Description
activated Boolean If true, all `Tour` emitted events will be displayed in console

Switch debug mode

defaults

property
Tour.defaults

Tour constructor option defaults

String

name

This option is used to build the name of the cookie where the tour state is stored. You can initialize several tours with different names in the same page and application.

name: "tour",

String

How to handle persistence

The value can be "Cookie" | "LocalStorage" | "Memory" (default "Memory") Note: the "Cookie" backend requires jquery.cookie.js

persistence: "Memory",

Boolean

Keyboard navigation

keyboard: true,

Function

Specify a function that return a css string

style: function() {
        return ".popover.bootstrap-tour.expose{z-index:99998;}\n#bootstrap-tour-overlay{background:rgba(0,0,0,0.5);display:none;width:100%;height:100%;position:absolute; top:0; left:0; z-index:99997;}";
      },

Object

Global step parameters

Each of the following parameters can be overriden at each step level.

step: {

String Function(step)

Default step title

title: null,

String Function(step)

Default step content

content: null,

String

Css class to add to the .popover element

Note: if `addClass` is defined at the step level. The two defined `addClass` will be taken into account in the popover

addClass: "",

Boolean

Globally enable an overlay for each step element, true if activated, false otherwise

overlay: false,

Boolean

Globally enable the reflex mode, click on the element to continue the tour

reflex: false,

Function

Option name Type Description
step Object The step to render

Bootstrap Tour step-wide template

The template should contain `.prev`, `.next` and `.end` will be removed at runtime by Bootstrap Tour if necessary.

template: function(step) {
          return "<div class=\"popover\">\n  <div class=\"arrow\"></div>\n  <div class=\"popover-inner\"><h3 class=\"popover-title\"></h3>\n    <div class=\"popover-content\"></div>\n    <div class=\"modal-footer\">\n    <a href=\"#\" class=\"btn end\">End tour</a>\n    <a href=\"" + step.prev + "\" class=\"btn pull-right prev\">Previous</a>\n    <a href=\"" + step.next + "\" class=\"btn pull-right next\">Next</a>\n    </div>\n  </div>\n</div>";
        }
      }
    };

stepDefaults

property
Tour.stepDefaults

addStep default parameters

String

Path to the page on which the step should be shown. this allows you
to build tours that span several pages!

path: "",

jQuery-object Css-Selector Function()

HTML element on which the step popover should be shown.

element: null,

String

How to position the popover - top | bottom | left | right.

placement: "right",

String Function(step)

Step title

title: "",

String Function(step)

Step content

Note: defining `step.title` and `step.content` functions at the tour level allow the developper to separate step title/content from the step behaviour.

content: "",

Boolean

Apply a css fade transition to the tooltip.

animation: true,

Boolean

Enable the reflex mode, click on the element to continue the tour

reflex: false,

String

Css class to add to the .popover element for this step only

addClass: ""

//@ sourceMappingURL=bootstrap-tour.js.map