Giter Club home page Giter Club logo

angular-bootstrap-tour's Introduction

angular-bootstrap-tour

Bower Version

jQuery-free version now available!

I have written a version of this plugin that uses Angular UI Bootstrap instead of Twitter Bootstrap and jQuery. It is now available at angular-ui-tour. Try it out!

About

This is a simple Angular wrapper around Bootstrap Tour. Simply add the "tour" directive anywhere, and add the "tour-step" directive to any element within "tour" that needs a tip.

All options are available by adding the corresponding attributes to the directive element.

There is also a "skip" option that if evaluates to true, will skip over the step.

This repository was scaffolded with generator-microjs.

Getting Started

Get the package:

bower install angular-bootstrap-tour

Add the script tags:

<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.js"></script>
<script src="bower_components/bootstrap-tour/build/js/bootstrap-tour.js"></script>
<script src="bower_components/angular-bootstrap-tour/dist/angular-bootstrap-tour.js"></script>

And the Bootstrap Tour CSS (or create your own):

<link rel="stylesheet" href="bower_components/bootstrap-tour/build/css/bootstrap-tour.css" />

Then add the module to your app:

angular.module('myApp', ['bm.bsTour']);

Configuration

The TourConfigProvider allows you to set a couple options:

  • prefixOptions {boolean, default: false} if set to true will require directive options to be prefixed to avoid conflicts
  • prefix {string, default: 'bsTour'} the prefix to use if prefixOptions is set to true

Use TourConfigProvider.set(<option>, <value>) in your app's config block to change the settings

You can use either tour and tourStep or bsTour and bsTourStep as directive names without changing config.

Examples

<div tour placement="top" on-end="onTourEnd(tour)" after-get-state="afterGetStateFunction" template-url="tour_template.html">
    <div id="mainMenu" tour-step title="Main Menu" content="{{mainMenuDescription}}" order="0" skip="pageName !== 'home'">
        ...
    </div>

    ...

</div>

Tour Directive

The tour directive creates a wrapper that contains all tour steps, and adds the tour object to the scope. If no options are specified, they all default to Bootstrap Tour's defaults. Values of event handler options will be evaluated against the tour's scope. For the afterGetState, afterSetState, and afterRemoveState, the value should evaluate to a function that takes 2 arguments, key and value. The container option should be a CSS selector, and defaults to "body". You can also pass an object to the tour-options attribute that will override any other attribute options.

TourStep Directive

The tour-step directive takes all the options available in Bootstrap Tour, with a few alterations. Instead of next and prev options, just use the "order" option. Order is used as a weighting (0 is first) and the plugin will dynamically determine which ones come before and after. If order is ommitted, it will default to 0. Multiple steps can have the same order, and those will display in the order that they are linked (usually the order in which they appear in the DOM.) If order is omitted from all tour-steps, the order will be whatever order in which they are linked. Steps can be skipped by passing the "skip" option an expression that evaluates to a boolean. The expression is evaluated before each step, so it can be a dynamic expression. This is useful if you have steps in a global layout, but only want to show them on the home page. Steps that are on hidden elements will not be shown. (Hidden means truly hidden, not obscured.) The title and contents options are watched, so an interpolated value can be passed.

Compatibility

I have tested it and found it working in the following browsers:

  • IE8, 9, 10, 11
  • Firefox 32
  • Chrome 37
  • Safari 7

TODO's

  • Write some tests!! (Come on Ben, stop being lazy ;p)

Build It Yourself

Assuming you have Node, grunt, and bower installed:

npm install

bower install

grunt

Demo

I have set up a simple demo using the Bootswatch Cerulean demo page (one of my favorite themes.) To run the demo run grunt demo and open demo/index.html in the browser.

Notes

I am using this in a personal project, but I haven't needed to use all the Bootstrap Tour options. This means that some of them might not be working due to the option values either not being passed correctly, or not being passed as interpolated values. If you run across any issues please report them with an example and I will fix them ASAP, or fork me and create a PR. You can now pass a template URL to either the tour or tour-step directives, and the template will be linked to whichever scope the template is specified on. (ie. if you add the template URL to the tour directive, it will always use the tour directive's scope, if you add it to a step, it will use the step's scope.) Alternatively, you can specify an expression that evaluates to a string that will be used as the template (using the "template" attribute.)

Thanks and enjoy!

License

(The MIT License)

Copyright (c) 2014

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

angular-bootstrap-tour's People

Contributors

bartvanderwal avatar benmarch avatar el-davo avatar tiddolangerak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

angular-bootstrap-tour's Issues

Backdrop is not working

Already added bakdrop configuration, but it's not working.

TourConfigProvider.set('backdrop',true);

New feature requests in jQuery-free version (let's call it 2.0)

Please comment with suggested features for version 2.0 which will primarily be a rewrite to exclude the jQuery dependency that exists in the current version. Just leave a very brief description of a feature you would like to see, and once I get a prototype into GH I can convert it into its own issue.

grunt error

When I try to execute the project with the instructions of MD file, specifically when I execute "grunt" I get this error:

Running "jshint:all" (jshint) task

Gruntfile.js
99 | bower_main: {
^ Identifier 'bower_main' is not in camel case.
app\tour_controller.js
118 | tour = new Tour(options);
^ 'Tour' is not defined.

2 errors in 8 files
Warning: Task "jshint:all" failed. Use --force to continue.

Aborted due to warnings.

Call tour.start() from controller

The tour is not initializing automatically by itself even with storage="false". And I do not want the tour to start from a button's ng-click function, but I would like it to be called immediately from within my controller.

I want to call tour.start() from within my module controller inside an init() function called every 60 seconds.

$scope.initTour = function() {
    $scope.tour.start();  <!-- insert code to call here -->
}

$scope.init = function() {
    MyService.getData().then(
        function(data) {
              $scope.data = data;
              $timeout($scope.initTour(), 2000);
        }
}

var interval = $interval($scope.init, 60000);

$scope.$on('$destroy', function() {
      $interval.cancel(interval);
});

But I cant get it to work.

Any help would be appreciated.

Thanks

Element - Step Options not working

I'm trying to get the the div containing the tour directive to get the popover to show over another html element.
It just seems to ignore the element setting.

"tour-step element="#element" order="1" title="Tour start" content="Welcome to the tour" placement="bottom"

Is there anyway for the popover to display over another element?

Requirment for bootstrap

The angular UI bootstrap works without bootstrap.js and jQuery.js

How possible it is to use this wrapper without bootstrap.js and jQuery.js? Can we use only CSS to style popups and angular to show them? Just like dropdowns in angular-ui-bootstrap?

starting tour from controller through ng-click is not working

//This is my controller for fraud-demo, when called it is calling the functions in bootstraptour.js rather than the angualr-bootstrap tour. How can i start the demo tour w.r.t angular-bootstrap tour

 $scope.steps = [
      {
          path:'/app/page1',
          element: "#tour1",
          title: "Title of my step",
          content: "content of the step",
          smartPlacement:true,
          placement:'left',
          orphan:true,
          reflex:true
      },
      {
          path:'/app/page2',
          element: "#tour-2",
          title: "Title of my step",
          content: "content of the step",
          placement:'right',
          autoScroll: true,
          smartPlacement:true,
          },
      {
          element: "#tour3,
          title: "Title of my step",
          content: "content of the step",
          smartPlacement:true,
          placement:'right',
          redirect: true,
      },

       $scope.tour =   new Tour({ //when hovered on 'Tour' it is displaying the function from bootstraptour.js
        storage: window.localStorage,
        backdrop: true,
        steps:$scope.steps,
        templateUrl:'app/demo.html'
     });

 $scope.showDemo = function (){ //this is the function i'm using for ng-click for a buttin link, ng-    click is working fine
       $scope.tour.init();
       $scope.tour.start();

   }

"template-url" attr doesn't run

I have a template-url attr on my body (where is tour attribute) and:

        function lookupTemplate(templateUrl, scope) {

            var template = $templateCache.get(templateUrl);

            console.log(templateUrl)
            console.log(template)

            if (template) {
                return compileTemplate(template, scope);
            }

            return null;

        }

and output is:

test.html
undefined

A tour-step does not put itself on scope

Hi! Great project! Very helpful.

A thing I'm missing is that the tour-step directive doesn't put 'itself' on the scope in the link function. You ARE doing this in the tour directive (see [ln 47]([tour directive]%28https://github.com/benmarch/angular-bootstrap-tour/blob/master/app/tour_directive.js%29)):

    //Initialize tour
    templateReady.then(function () {
        scope.tour = ctrl.init(tour); /// <- this line
        scope.tour.refresh = ctrl.refreshTour;
    });

Could you add a similar thing in the tour_step? (e.g. here on line 94)

    //Add step to tour
    templateReady.then(function () {
        scope.step = step;  // <-- Please add this line here!!
        ctrl.addStep(step);
    });

I understand that this is not needed by your code. But that gives me a hook to extend your directive with another custom directive. I could also clone your project and do a PR if you prefer that! Let me know.

Background:
I'm working an extension. I'm using your directives as much as possible, but extended them with two custom ones so all things like 'title', 'content', et.c can also be set in one single place in a config object. That way we don't have to put them within the HTML directly. That would litter the views in our project with a lot of code. Furthermore the config could then also be retreived and saves in the backend, for instance to allow dynamic customization per user.

Connecting the tour steps to certain places in the DOM/view is still done with your 'tourandtour-step` directives. But only a name needs to be specified to make the connection to the stuff in config.

Ending opened tour when i switch page/redirection

Hello,
i'm having a small problem, i have set my tour to start automatically when i enter a certain page/controller, but when i go to another page/controller with the tour opened, it doesn't close. And i can't close it manually anymore.

Maybe i've set it all wrong from the begining, i got a hidden button with ng-click="tour.restart(true)" which is clicked in my controller.

How can i make it close itself on page switching ?

How to use angular-bootstrap-tour with angular 4 and Typescript

How can I use angular-bootstrap-tour with angular 4 and Typescript.
Normaly I Import third Party Code inside my app.model.ts file like that:

// angular
import { Inject, NgModule, PLATFORM_ID } from '@angular/core';
import { Http } from '@angular/http';
import { RouterModule } from '@angular/router';

// libs
import { ConfigLoader, ConfigService } from '@ngx-config/core';
// TODO: ngx-i18n-router
// import { I18N_ROUTER_PROVIDERS, I18NRouterLoader, I18NRouterModule, RAW_ROUTES } from '@ngx-i18n-router/core';
import { MetaLoader } from '@ngx-meta/core';
import { TranslateLoader, TranslateService } from '@ngx-translate/core';
import { PerfectScrollbarConfigInterface, PerfectScrollbarModule } from 'ngx-perfect-scrollbar';

// framework
import { configFactory, CoreModule, metaFactory } from './framework/core/core.module';
import { SharedModule } from './framework/core/shared.module';
import { MaterialModule } from './framework/material/material.module';
import { HttpInterceptorModule } from './framework/http/http-interceptor.module';
import { ChangeLanguageComponent, I18NModule, translateFactory } from './framework/i18n/i18n.module';
import { AnalyticsModule } from './framework/analytics/analytics.module';

// routes & components
import { routes } from './app.routes';
import { AppComponent } from './app.component';
import { LAYOUT_COMPONENTS } from './components/layout';
import { LOGIN_COMPONENTS } from './components/login';

import { MentoringService } from './components/services';

//import { LandingPageComponent } from './components/landingPage/landingpage.component';


const PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
  suppressScrollX: true
};

@NgModule({
  imports: [
    RouterModule.forRoot(routes),
    MaterialModule,
    PerfectScrollbarModule.forRoot(PERFECT_SCROLLBAR_CONFIG),
    CoreModule.forRoot([
      {
        provide: ConfigLoader,
        useFactory: configFactory,
        deps: [
          PLATFORM_ID,
          Http
        ]
      },
      {
        provide: MetaLoader,
        useFactory: metaFactory,
        deps: [
          ConfigService,
          TranslateService
        ]
      }
    ]),
    SharedModule,
    HttpInterceptorModule,
    I18NModule.forRoot([
      {
        provide: TranslateLoader,
        useFactory: translateFactory,
        deps: [
          PLATFORM_ID,
          Http
        ]
      }
    ]),

    // TODO: ngx-i18n-router
    // I18NRouterModule.forRoot(routes, [
    //   {
    //     provide: I18NRouterLoader,
    //     useFactory: i18nRouterFactory,
    //     deps: [
    //       ConfigService,
    //       RAW_ROUTES
    //     ]
    //   }
    // ]),
    AnalyticsModule
  ],
  declarations: [
    AppComponent,
    LOGIN_COMPONENTS,
    LAYOUT_COMPONENTS
  ],
  exports: [AppComponent],
  entryComponents: [ChangeLanguageComponent],
  bootstrap: [AppComponent],
  providers: [MentoringService]
})
export class AppModule {
  constructor(@Inject(PLATFORM_ID) private readonly platformId: any) {
  }
}

I do not understand how I can do that with the UI-TOUR plugin.
I'm quite new to angular and typescript, so it would be great to get some help from you!

Skip doesn't work in ng-repeat

Hi!

I'm trying to put a tour step on an item inside a ng-repeat, and just noticed the "skip" option doesn't work โ€” I'm guessing because ng-repeat creates its own child scope. Using 0.3.2 btw.

ng-click inside template

Hi,

I'm using template-url as an attribute for tour-step to link an inline template. The template has a button with ng-click="test()". test() is defined on the scope where tour-step is created. Clicking the test button doesn't execute test() though.
I think the scope's get confused somehow, but I can't find a way around it. Any ideas?

Ignores step in bootstrap modal

When I have a step inside a modal it seems to skip this step and continues to the next step on the page. I have the bootstrap opened via a jquery call. However if you have the modal opened before the tour start then it continues that step.

I've tried delaying the on-next function while the modal opens but that doesn't seem to work, any ideas?

Duration

Duration only seems to work on the tour, not the tour-step.

Scenario is... I want some steps to just move you along, but other require deliberate action.

template-url option not working

Without template-url everything works great, but when I'm trying to add this option I'm getting a jquery error:

Uncaught TypeError: Cannot read property 'ownerDocument' of undefined

Step config only through directives ?

Hi

Is there a possible way to handle steps tour with JS instead of directives ? Like the standard bootstrap-tour ? :

var tour = new Tour(
  steps: [
  {
    element: "#my-element",
    title: "Title of my step",
    content: "Content of my step"
  },
  {
    element: "#my-other-element",
    title: "Title of my step",
    content: "Content of my step"
  }
]);

In my module-driven angular app, adding directives all over my templates is not an option . I need a dedicated and separated module for that.

Thanks for this module anyway

How to handle steps that are not rendered on tour start?

I have steps that will not be part of the DOM on tour start. For example, content (w/ tour-steps) rendered as the results of an async service call, modals that are displayed on next step. How can I get bs tour to re-check for these steps?

Thank you.

Demo

Any chance of getting a demo put on here? I've followed your directions and everything seems to be loaded, but not getting any tour pop ups. Also not seeing the tour object getting created in my scope. Would be cool to see in it's entirety how you have it set up to work.

Rename `stepId` to `id`

Currently, the value of tour-step attribute is assigned to step.stepId (

). As far as I understand this stepId property is used internally to identify steps (
if (step.stepId === waitForStep) {
).

According to sorich87/bootstrap-tour#44 the original bootstrap-tour defines step.id to identify the steps. In addition it set the id attribute of popover window to the same value.

IMHO, it makes sense to stay aligned/consistent with bootstrap-tour and rename stepId to id.

Multiple Tours

I see you can add a name to a tour, and Bootstrap Tour's documentation states this.
I don't see how you add steps to a specific tour and also don't see how you start a specific tour.

template-url is not working

when I am adding new template its not working. I am getting error as 'elem.cloneNode is not a function' is not function. My template is very similar which you are using.

<div class='popover tour'>
  <div class='arrow'></div>
  <h3 class='popover-title'></h3>
  <div class='popover-content'></div>
  <div class='popover-navigation'>
    <button class='btn btn-default' data-role='prev'>First</button>
    <span data-role='separator'>|</span>
    <button class='btn btn-default' data-role='next'>Last</button>
    <button class='btn btn-default' data-role='end'>End</button>
  </div>
</div>

I am also getting same template in lookupTemplate as you mentioned.

XHR finished loading: GET "http://localhost:9000/views/tour_template.html".
(anonymous function) @ angular.js:10765
sendReq @ angular.js:10558
serverRequest @ angular.js:10268
processQueue @ angular.js:14792
(anonymous function) @ angular.js:14808
Scope.$eval @ angular.js:16052
Scope.$digest @ angular.js:15870
Scope.$apply @ angular.js:16160
bootstrapApply @ angular.js:1679
invoke @ angular.js:4523
doBootstrap @ angular.js:1677
bootstrap @ angular.js:1697
angularInit @ angular.js:1591
(anonymous function) @ angular.js:29013
fire @ jquery.js:3099
self.fireWith @ jquery.js:3211
jQuery.extend.ready @ jquery.js:3417
completed @ jquery.js:3433
angular-bootstrap-tour.js:292 template us<div class='popover tour'>
  <div class='arrow'></div>
  <h3 class='popover-title'></h3>
  <div class='popover-content'></div>
  <div class='popover-navigation'>
    <button class='btn btn-default' data-role='prev'>First</button>
    <span data-role='separator'>|</span>
    <button class='btn btn-default' data-role='next'>Last</button>
    <button class='btn btn-default' data-role='end'>End</button>
  </div>
</div>

Center placement for element step

Is this possible? I want to just tie the tour step with a container element first and just like to show the step at the center of the element / (or center of screen would be better).

Appreciate the advice.
Vicente

apply tour-step to ng-repeat

Hi ,

I am showing multiple div using ng-repeat. I want to show tooltip for my first div only. Is there any way,
( Please note I do want to apply for my all div. Just first div only)

onStart and onEnd not working?

I am trying to call a function in my controller on an element with a tour using:

on-end="end(tour)"
$scope.end = function (tour) {
        localStorage.set('tour-ended');
};

But I cant get it to work. I can use onShow, OnNext, OnHide etc, but not onEnd and start for some reason.

Any help would be appreciated.

Thanks

Option to lock controls

Option to lock controls when tour is on.. (meaning user cannot do anything else but go through the tour)

Is there such an option that can be configured? Possible to include?

Thanks

Kind Regards,
Vicente

Multiple page tour using bootstrap tour

I am using angular-bootstrap-tour for the tour feature in my app. It is working fine for the same page but the ordering is not proper when it comes to different pages.

I am using angularjs state provider
first page code

  <li ui-sref-active="current" style="width: 33.33%;padding-top:6px;border-top:0" id="step1" class="ibox-title" on-Next="checkTour(tour)" tour-step order="1" title="1 Company Profile" backdrop="true" on-Hidden="clearbody(tour)"  on-Shown="preparebody(tour)"  content="This is a 1 step on our tour. You can easy set a Company Profile." placement="top"><a ui-sref=".company_profile" class="btn-default ellipsisClass"><span>1</span> Company Profile</a></li>

Second Page Code :

     <button class="btn btn-info" type="button" ng-click="openImportUsers();" class="ibox-content text-center" id="step2" order="2" tour-step="step2" title="Import Users" on-Next="checkTour(tour)" backdrop="true" on-Hidden="clearbody(tour)" on-Shown="preparebody(tour)" content="You can import multiple users." placement="left">Import Users</button>

When i do next from first page li tag then it is jumping to the same page other order instead of Second page order 2. Please provide some help in this.

Orphan mode does'nt work...

hello @benmarch!

i have an issue with your plugin.
i cant get the .orphan class on the popover

here is a part of my code:

<body tour reflex="true" orphan="true">
  <nav class="navbar" tour-step order="4" title="" content="lorem" orphan="true">
  ...

and in the rendered html, no orphan class...
image

any idea?

thanks!

Is this project maintained?

In bower I see that this project depens on angular 1.2 ans bootstrap-tour 0.9.3 so it's rather old.
Is it maintained?

ng-route dependency is redundant

Does the package really depend on ng-route?

As I can see ng-route is required just for the demo app. If that's the case, why not moving ng-route to dev-deps?

Scope tour does not bind to controller as syntax

I cant bind tour to my controller i get undefined. why this is happen?

class FeedController {

  constructor( $scope ) {
    $scope.$watch('tour', function( newVal, oldVal ) {
      console.log(newVal, oldVal); // is undefined
    });
  }
}
  <div class="row" tour orphan="true" storage="false">
 </div>

Not supporting the element attribute?

I want to highlight a nested element, is this possible? I am using angular datatables in my app and want to highlight the search input.

<table id="myTable" datatable="ng" ...

Datatables names this search input (tablename)_filter, so in bootstrap-tour I was able to highlight this input (I'm using backdrop) by configuring the step with what I knew the element's name would be:

element: "#myTable_filter"

I am trying to switch from bootstrap-tour to angular-bootstrap-tour because it is working better in my Angular SPA. But in angular-bootstrap-tour I can't seem to get this to work by including the same attribute

<table id="myTable" datatable="ng" tour-step element: "#myTable_filter"...

Likewise in bootstrap-tour I've been able to configure a nested element by looking for the first element of a given type such as:
element: someElement > input:first-of-type

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.