A framework to make it easy for developers to add product tours to their pages.

Overview

🚨 UNMAINTAINED 🚨

This project is no longer used by LinkedIn and is currently unmaintained.

Hopscotch Build Status

Hopscotch is a framework to make it easy for developers to add product tours to their pages. Hopscotch accepts a tour JSON object as input and provides an API for the developer to control rendering the tour display and managing the tour progress.

To learn more about Hopscotch and the API, check out linkedin.github.io/hopscotch.

Example Hopscotch tour

What's Here?

  • /archives contains .zip and .tar.gz files of prior and current distributions of Hopscotch.
  • /demo has a simple demo page with a Hopscotch tour. Much of the content duplicates what's on the github.io page.
  • /dist includes compiled files for the current version of Hopscotch. This folder gets zipped up into an archive when a new release is published.
  • /src contains source files for Hopscotch, including JavaScript and Less. If you're making changes to contribute back to the core repository, this is where you'll want to make them.
  • /test is our testing suite for the core framework, written using Jasmine.

How do I get started with Hopscotch?

The Hopscotch files included in /dist is a good starting point for working with Hopscotch. Out of the box, Hopscotch includes the core JavaScript for running and interacting with tours, a default template for rendering bubbles, and a default CSS file to provide a basic look and feel for your tours. To get started, simply include these files on your page, then use the Hopscotch API to start a tour. While Hopscotch will use YUI or jQuery if they're present, they're not required.

Check out linkedin.github.io/hopscotch for usage examples and a live sample tour. If you'd like to tweak some of the default assets included with Hopscotch to best suit your project's needs, read on for details about how to modify and rebuild a custom version of Hopscotch.

How do I build Hopscotch?

Hopscotch is built using Grunt.js. Learn more about how to get started with Grunt. Running grunt will build Hopscotch (publishing artifacts to /tmp) and run the test suite against the newly built artifacts.

How do I test Hopscotch?

Testing is done as part of the build process using the Jasmine testing framework. You can run grunt test to verify changes.

Continuous integration is run against every pull request using Travis CI. Please verify your changes against the test suite before submitting a pull request! We also recommend adding new tests for any new features or bugfixes as feasible.

How do I tweak Hopscotch to meet my project's requirements?

Depending on your use case, you might want to modify and/or rebuild some of the basic components included with Hopscotch. Some moddable options include...

  • CSS tweaks: The Hopscotch stylesheet is written in and compiled using LESS. If you make changes to your local copy of these stylesheets, they'll be recompiled when building Hopscotch.
  • Bubble markup: The internal markup for Hopscotch bubbles are rendered using templates. See the README.md file in /src/tl for details. Any templates in /src/tl will be compiled into JavaScript using JST when building Hopscotch and included at the bottom of Hopscotch.js.
  • Callbacks & Page Interactivity: See linkedin.github.io/hopscotch for details about the Hopscotch API and what tour/callout events you can register events with. Use callbacks to integrate Hopscotch with other libraries and/or presentational elements you might have on your page.

I want to contribute! How can I help?

Note: We're currently in the midst of refactoring Hopscotch into a newer module-based format that should help make readability and maintenance a lot easier. While this work is in progress, we'll be halting changes to the master branch of Hopscotch, apart from major maintenance fixes. Please feel free to continue submitting bug reports, though do keep in mind that they not be addressed in the current iteration of the library. Thanks!

See CONTRIBUTING.md for details on how to contribute back to the public Hopscotch repository on GitHub.

Comments
  • option to append hopscotch div to specified element instead of body

    option to append hopscotch div to specified element instead of body

    In some cases, append the entire hopscotch element to the body is undesirable. For example, angular apps use many templates and you don't want the tour bubbles persisting between different views. This PR allows a user to specify an appendTo to a tour to specify which element to append the hopscotch element to. If the element doesn't exist, the hopscotch element will be appended to the body.

    opened by stickperson 18
  • i18n example

    i18n example

    Could we have an example of i18n working? I made this:

    var retour = {
      id: "tutorial-user-creation",
      steps: [
                      {
                        title: "Tutorial is here",
                        content: "At any time you can press this button to restart the tutorial.",
                        target: '#restart_tutorial',
                        placement: "bottom",
                        xOffset: -15,
                        showNextButton: true,
                        showPrevButton: true
                      },
      ],
      i18n.nextBtn: "Próximo"
    };
     hopscotch.startTour(retour);
    

    ...and it returns me the error "Uncaught SyntaxError: Unexpected identifier". In the documentation it says it accepts string. What is wrong with that?

    Thank you.

    opened by bsides 16
  • How to reinitialize hopscotch

    How to reinitialize hopscotch

    Hi i'm using hopscotch in a rails app that uses Turbolinks. On an initial page load of the app I can trigger hopscotch tours manually with hopscotch.startTour When switching to a new page with Turbolinks I can call the hopscotch api methods, startTour GetCurrStepNo GetCurrTour they look successful but hopscotch doesn't render any DOM elements. I'm thinking some hook or event or something gets wiped in the Turbolinks page load and needs to be reestablished.

    bug 
    opened by kevzettler 13
  • How to set up onNext function, when using a database to set up the steps properties?

    How to set up onNext function, when using a database to set up the steps properties?

    Hello, in my project, I dynamically create tours and steps from values retrieved from a database. So far I wasn't able to assign a function, i.e. to the onNext property. The problem is that the function is retrieved as a string from the database. So I end up with something like the following, which I guess is no surprise that it doesn't work.

    content: "Test Content..." onNext: "function(){alert('help!');}" placement: "top"

    opened by karapapas 11
  • Support arbitrary selectors for targets

    Support arbitrary selectors for targets

    Cause why not? For my team, this was the expected behavior and hopscotch does not currently throw a useful error message when it does not get what it expects. We were confused when encountering exceptions when given a perfectly valid selector, especially since the code that calls this handles multiple matches gracefully.

    This implementation passes all tests that are currently passing in master, and preserves backwards compatibility for existing calls to getStepTargetHelper.

    core-enhancement 
    opened by joshjordan 10
  • Callout Function throws error: Uncaught TypeError: Cannot read property 'getBoundingClientRect' of null

    Callout Function throws error: Uncaught TypeError: Cannot read property 'getBoundingClientRect' of null

    Copied and pasted the exact callout code from the Hopscotch demo to test in my page

    var calloutMgr = hopscotch.getCalloutManager();
    calloutMgr.createCallout({
      id: 'attach-icon',
      target: 'attach-btn',
      placement: 'bottom',
      title: 'Now you can share images & files!',
      content: 'Share a project you\'re proud of, a photo from a recent event, or an interesting presentation.'
    });
    

    this results in Chrome throwing errors: Uncaught TypeError: Cannot read property 'getBoundingClientRect' of null

    and

    Uncaught Error: Callout by that id already exists. Please choose a unique id.

    bug 
    opened by txshan 9
  • Deprecated gradient warnings

    Deprecated gradient warnings

    Looks like the gradient syntax changed a bit:

    autoprefixer: /tmp/build/node_modules/hopscotch/dist/css/hopscotch.css:290:3: Gradient has outdated direction syntax. New syntax is like "to left" instead of "right".
    
    autoprefixer: /tmp/build/node_modules/hopscotch/dist/css/hopscotch.css:299:3: Gradient has outdated direction syntax. New syntax is like "to left" instead of "right".
    
    autoprefixer: /tmp/build/node_modules/hopscotch/dist/css/hopscotch.css:311:3: Gradient has outdated direction syntax. New syntax is like "to left" instead of "right".
    
    autoprefixer: /tmp/build/node_modules/hopscotch/dist/css/hopscotch.css:320:3: Gradient has outdated direction syntax. New syntax is like "to left" instead of "right".
    
    code-cleanup 
    opened by matthewmueller 8
  • Add error callback for showStep (Issue #274)

    Add error callback for showStep (Issue #274)

    Calling showStep without a proper step target fails, but the tour error callback is not invoked. This change fixes that, and sets the current step number to the step that failed for debugging purposes

    I'm getting a different error in my codepen example (used in the issue report) related to the 'bubble_default' template, so I wasn't able to test this. I do have this fix in a client code-base however, and that is working fine.

    This may be imperfect, if so I apologize. Just thought I'd try to get this in for the maintenance release if possible.

    opened by travstone 7
  • Restarting tour from beginning on page reload

    Restarting tour from beginning on page reload

    I'm having difficulty getting the tour to restart at the first step after page reload.

    I've tried specifying a step in the startTour() function, and I've tried using showStep() passing in the first step in as an argument. Neither of these have worked (nor have they thrown an error).

    As far as I know, there's no easy way to disable sharing data between sessions.

    Could you point me in the right direction?

    duplicate 
    opened by jessp 7
  • Don't cache step targets

    Don't cache step targets

    Caching step targets causes problems with web apps that modify the DOM.

    I suggest that it's an unnecessary optimization, that would be better removed.

    bug 
    opened by joehalliwell 7
  • Use compiled templates for rendering internals of bubble

    Use compiled templates for rendering internals of bubble

    There are a couple of current enhancements for configuration changes that affect the internals of each Hopscotch bubble (#33 and #39). I'm thinking, instead of creating new configuration options that affect the bubble display (which could lead to a bloated configuration object over time), what if we could provide the option to use a JavaScript template (or other method) to render the internals of each bubble?

    How it would work

    A user could define a render method in their tour configuration options or register a template via hopscotch.registerTemplate(Function render). Hopscotch would be agnostic to how this template is written or compiled... all it cares about is a method that it can hand an object off to for rendering the bubble's internals. The object itself would contain information relevant to the current step (title, content, stepNum, totalSteps, button info, labels) and would be responsible for returning HTML that can be set as the bubble's innerHTML.

    Other contemplations

    • How to handle events? One possibility is to include some means when declaring the template to provide the IDs that Hopscotch should attach events to. Or, we could have Hopscotch pass a DOM reference to the render method and require it to handle attaching the events.
    • Should render() be limited in its scope to just the inside of the bubble, or should it have responsibility for the structure of the whole bubble? The latter might require some updates to positioning calculations.
    • If we go this route, we may want to consider modifying how Hopscotch currently does bubble rendering to use this new pattern instead.

    Any thoughts?

    core-enhancement 
    opened by timlindvall 7
  • hopscotch and iframes

    hopscotch and iframes

    We have a webservice with same domain iframes and we have the tour script and hopscotch source code in the top document.

    These are the iframes:

    <button id="startTourBtn" onClick="hopscotch.startTour(tour);" class="btn btn-large btn-primary">Take a tour</button>
    	<div class="wrapper">
    		<div class="container_left" id="resizable">	
    			<div class="container_publications">	
    				<iframe name="list_publications" id="list_publications" marginwidth="0" allowtransparency="true" frameBorder="0" scrolling="yes"></iframe>
    				<iframe name="media_timeline" id="media_timeline" marginwidth="0" allowtransparency="true" frameBorder="0" scrolling="no"></iframe>
    			</div>
    		</div>
    		<div class="container_right">		
    			<div class="container_read_media">
    				<iframe name="flip_publication" id="flip_publication" allowfullscreen marginwidth="0" frameBorder="0" allow="encrypted-media" scrolling="yes">
    			</div>
    		</div>
    	</div>
    

    Please let us know how to write the tour to reference elements in the iframes. Here are some examples of what we've done so far - none of the tries have been working:

    var tour = {
      id: "introduction_tour",
    	showPrevButton: true,
    	showNextButton: true,
      steps: [
    	{
    	  title: "Guided tour",
    	  content: "This starts a guided tour of the application.",
    	  target: "startTourBtn",
    	  placement: "bottom"
    	},
    	{
    	  title: "Searching the system",
    	  content: "This is where you enter a search",
    	  target: "q",
    	  placement: "bottom"
    	},
    	{
    	  title: "The publications",
    	  content: "Here are the publications. Click on the thumbnail to read/watch/listen. Click on text under thumbnail to read publication data.",
    	  target: "$('#list_publications').contents().find('.article-container')",
    	  placement: "right"
    	}
      ]
    };
    

    Thanks for any help!!

    opened by ltulib 0
  • Visibility for templating and `setRenderer`

    Visibility for templating and `setRenderer`

    Wondering why documentation for templates is hidden in https://github.com/linkedin/hopscotch/tree/master/src/tl and no mention within documentation at http://linkedin.github.io/hopscotch/

    Are these methods not expected to be public?

    It seems like providing templates for bubbles is a pretty typical use case. It would be useful to include a template property in the TourDefinition and StepDefinition interfaces. If a template isn't provided then should use default template.

    Also setRenderer isn't defined on the type for Hopscotch https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/hopscotch/index.d.ts#L81-L161

    opened by ALJCepeda 1
  • Is it possible to fixe the

    Is it possible to fixe the "popup" on not fixed target

    Hi,

    I'm trying to create my first tour with Hopscotch, but I'm having a problem. The "popup" is well positioned but when I scroll the popup move. I know the property "fixedElement" but I can't use it because the target can't be fixed on this page.

    Is there another way to do this ?

    Thank's

    opened by LeoLR 0
  • sprite-green and sprite-orange don't work

    sprite-green and sprite-orange don't work

    hopscotch pulls the images from hopscotch.min.css

    link rel="dns-prefetch" href="https://github.githubassets.com" link rel="dns-prefetch" href="https://avatars0.githubusercontent.com" link rel="dns-prefetch" href="https://avatars1.githubusercontent.com" link rel="dns-prefetch" href="https://avatars2.githubusercontent.com" link rel="dns-prefetch" href="https://avatars3.githubusercontent.com" link rel="dns-prefetch" href="https://github-cloud.s3.amazonaws.com" link rel="dns-prefetch" href="https://user-images.githubusercontent.com/

    and from here:

    .hopscotch-bubble-close{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:0;color:#000;background:transparent url(../img/sprite-green.png) -192px -92px no-repeat;display:block;padding:8px;position:absolute;text-decoration:none;text-indent:-9999px;width:8px;height:8px;top:0;right:0}div.hopscotch-bubble .hopscotch-bubble-close.hide,div.hopscotch-bubble .hopscotch-bubble-close.hide-all{display:none}div.hopscotch-bubble .hopscotch-bubble-number**{background:transparent url(../img/sprite-green.png)**

    opened by PsychoIndigo 2
Releases(v0.3.1)
  • v0.3.1(Jun 2, 2017)

  • v0.3.0(Jun 2, 2017)

  • v0.2.8(May 4, 2017)

  • v0.2.7(Feb 25, 2017)

  • v0.2.6(Jul 1, 2016)

    • #287 Add new items to .gitignore (ported over from gh72).
    • #275 Update jasmine version in package.json
    • #273 Fix unlisten method (wrong callback equals)
    • #253 Improve documentation of the target attribute of step elements.
    • #280 Miss a variable declaration
    • #291 Add error callback for showStep (Issue #274)
    Source code(tar.gz)
    Source code(zip)
  • v0.2.5(Jul 20, 2015)

    • #188 [GH-188] No event called after tour is finished
    • #193 [GH-190] Close button should be a button
    • #187 [GH-24] Recover when tour bubble DOM element is destroyed
    • #183 Remove moot version property from bower.json
    • #181 Remove all styling from hopscotch.less
    • #182 [GH-175] totalSteps should be i18n-ified
    • #178 [GH-177] Require existing target element for stand-alone callouts
    • #176 [GH-172] documentIsReady is when document.readyState is complete
    Source code(tar.gz)
    Source code(zip)
  • v0.2.4(Apr 28, 2015)

    • #168 Gracefully handle steps without valid target
    • #167 Hide previous button on first step, even if steps are skipped.
    • #153 Tour ID as part of classes
    • #151 Add support for AMD and CommonJS
    • #146 Check tour & callout IDs for invalid characters
    • #142 Simple bower config file added.
    Source code(tar.gz)
    Source code(zip)
  • v0.2.3(Dec 10, 2014)

    • #139 RefreshBubblePosition updates all known callouts
    • #136 Ignore skipped steps in numbering
    • #137 NextOnTarget Click event not always removed
    • #133 Add right-to-left support to hopscotch
    • #128 Trailing comma in opts.i18n object
    • #126 Revert default z-index to empty vs auto
    • #102 Callbacks on callouts do not work
    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Jun 29, 2014)

    • #91 Don't cache step targets - support for single page apps
    • #96 box-sizing: content-box - Issues with Bootstrap 3
    • #90 Prefer jQuery and Sizzle when searching for a target
    • #94 Catch exceptions caused by illegal targets in document.QuerySelector
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Mar 25, 2014)

    • #70 Rendering tour & callout bubbles using compiled templates (@zimmi88)
    • #62 Add method to redraw the bubble at a new position (@cedrics)
    • #64 Add changelog (@kate2753)
    • #61 Reorganize repo and automate release process, travis integration (@kate2753)
    Source code(tar.gz)
    Source code(zip)
  • v0.1.3(Mar 25, 2014)

    • aaca52b Update README: add explanation for the getCurrTarget() (@gnatok)
    • d5894b2 Move window.sessionStorage into try catch block. (@nanek)
    • 35a2b2d detect when a onNext/onPrev callback updates tour state (@gkoo)
    • 4c025eb a little cleanup from the previous commit (@gkoo)
    • 25140fb Changed logic to check for typeof currStepNum. Forcing tour to start at step 0 was not working. (@leedavidr)
    • bc2af92 makes onCTA use callback helpers (@yeah)
    • 7791d6f Small doc update for query selectors. (@marc-hughes)
    • 0fbef13 Support arbitrary selectors for targets (@joshjordan)
    Source code(tar.gz)
    Source code(zip)
Owner
LinkedIn's Attic
The OSS projects that LinkedIn no longer maintains live here.
LinkedIn's Attic
Simple, flexible tours for your app

Tourist.js Tourist.js is a simple library for creating guided tours through your app. It's better suited to complex, single-page apps than websites. O

null 1.2k Dec 6, 2022
It is a tours website for showing the information about all the tours of this company and making the clients able to book them.

NATOURS APP Table of Contents Deployed Website Built With Getting Started Description Documentation Screenshots Deployed Website : NOTE: Heroku is pla

null 3 Sep 24, 2022
Quick and easy product tours with Twitter Bootstrap Popovers

Bootstrap Tour Quick and easy way to build your product tours with Bootstrap Popovers. Compatible with Bootstrap >= 2.3.0 Demo and Documentation http:

Ulrich Sossou 4.4k Dec 23, 2022
A Gatsby starter using the latest Shopify plugin showcasing a store with product overview, individual product pages, and a cart

Gatsby Starter Shopify Kick off your next Shopify project with this boilerplate. This starter creates a store with a custom landing page, individual f

Brent Jackson 12 May 12, 2021
A simple, lightweight, clean and small library for creating guided product tours for your web app.

Tourguide.js Simple, lightweight library for creating guided tours for your web, apps and more. A tour guide is a person who provides assistance, info

Docsie.io 277 Dec 12, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
We are creating a Library that would ensure developers do not reinvent the wheel anymore as far as Authentication is concerned. Developers can easily register and download authentication codes that suits their need at any point.

#AuthWiki Resource Product Documentation Figma Database Schema First Presentation Live Link API Documentation Individual Contributions User Activity U

Zuri Training 17 Dec 2, 2022
A full-stack application for junior developers to find jobs that match their skill-level, find gigs in order to boost their resume, and showcase a portfolio.

Junior is a full-stack web application that was created to facilitate junior developers in finding jobs that match their skill-level, boosting their resume through finding and completing gigs, and providing a way to easily showcase a portfolio

Karolina 5 Oct 25, 2022
See a banned user's profile, their friends, their favorite games, their followers etc.

Roblox-Banned-User-Viewer AKA BanView See a banned user's profile, their friends, their favorite games, their followers etc. Ever wondered how to view

SCR1PP3D 4 Nov 18, 2022
Simple, flexible tours for your app

Tourist.js Tourist.js is a simple library for creating guided tours through your app. It's better suited to complex, single-page apps than websites. O

null 1.2k Dec 6, 2022
Boost is a Microsoft Excel Add-in to help developers import large excel workbooks into their database using SQL queries

Microsoft Excel Add-in for Developers About Us Boost is a Microsoft Excel Add-in to help developers import large excel workbooks into their database u

OSLabs Beta 30 Sep 30, 2022
This project was created to help discord.js developers start their own bot, you can take this project as a basic for your bot and add things to it as you want. 🙂

Discord.js Starter-Bot A small & basic discord.js bot to help you get started ??️ This project was created to help discord.js developers start their o

Strike 3 Nov 29, 2022
Adds links to Discogs pages from various sites. Auto search for music on torrent and other sites. Does multi auto-search on Artist/Discography pages. Auto search local HDDs/filelists using Voidtools Everything search engine.

Discogs Scout: Adds links to Discogs pages from various sites. Auto search for music on torrent and other sites. Does multi auto-search on Artist/Disc

null 27 Dec 27, 2022
Add animation to your HTML5 pages, items and on text, using this JS Framework

animate.js is a tiny JavaScript library that provides a convenient way to apply Animate.css powered CSS animations to DOM elements without writing any

Rohit Chouhan 9 Oct 25, 2022