/*jslint browser: true*/ /*global console, Framework7, alert, Dom7, Template7*/ /** * A plugin for Framework7 to help you with a tour guide within your app * * @module Framework7/prototype/plugins/tourguide * @author www.timo-ernst.net * @license MIT */ Framework7.prototype.plugins.tourguide = function (app) { 'use strict'; // Variables in module scope var $$ = Dom7, t7 = Template7, defaultTourGuideTemplate, TourGuide; /** * Represents the tour guide * * @class * @memberof module:Framework7/prototype/plugins/tourguide */ TourGuide = function (tourSteps, options, currentStep) { // Private properties var self = this, defaults = { previousButton: false, nextButtonText: 'Next', endTourButtonText: 'Done', previousButtonText: 'Previous', template: defaultTourGuideTemplate, customCSS: 'tour-guide-popover' }, template, options = options || {}, tourSteps = tourSteps || [], currentStep = currentStep || 0; function setDefaultTemplate () { defaultTourGuideTemplate = '
'; }; self.setMoveForwardAction = function () { // Click handler to move forward on tour $$(document).on('click', '.tour-guide-next-button', function (e) { e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); currentStep++; if (tourSteps.length === currentStep) { console.log('No more steps'); } else { console.log('Next step'); } self.showTour(tourSteps, currentStep); }); }; self.setMoveBackwardAction = function () { // Click handler to move forward on tour $$(document).on('click', '.tour-guide-previous-button', function (e) { e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); console.log('previous step'); currentStep--; self.showTour(tourSteps, currentStep); }); }; self.moveFoward = function () { if (+currentStep === tourSteps.length) { console.log('Last step, cannot move forward.'); return; } currentStep++; if (tourSteps.length === currentStep) { console.log('No more steps'); } else { console.log('Next step'); } self.showTour(tourSteps, currentStep); }; self.moveBackward = function () { if (+currentStep === 0) { console.log('First step, cannot move backwards.'); return; } currentStep--; if (tourSteps.length === currentStep) { console.log('No more steps'); } else { console.log('Next step'); } self.showTour(tourSteps, currentStep); }; /** * Shows the tour guide * * @public * @memberof module:Framework7/prototype/plugins/tourguide */ self.showTour = function () { setTimeout(function () { try { // close previous modal if exists app.closeModal(); // terminate tour if (currentStep === (tourSteps.length)) { if (typeof tourSteps[currentStep] !== 'undefined' && tourSteps[currentStep] !== null && typeof tourSteps[currentStep].action !== "undefined" && tourSteps[currentStep].action !== null && typeof tourSteps[currentStep].action === "function") { tourSteps[currentStep].action(); } currentStep = 0; return; } if (typeof tourSteps[currentStep].action !== "undefined" && tourSteps[currentStep].action !== null && typeof tourSteps[currentStep].action === "function") { tourSteps[currentStep].action(); } /* * popover arguments: * - tourStep html * - tourStep element * - removeOnClose * - animated * - closeByOutside */ app.popover(tourSteps[currentStep].html, tourSteps[currentStep].element, true, true, false); } catch (framework7NotReadyException) { console.log("Framework7 is not ready yet"); console.log(framework7NotReadyException); } }, 100); }; /** * Sets the options that were required * * @private */ function applyOptions() { var def; options = options || {}; for (def in defaults) { if (typeof options[def] === 'undefined') { options[def] = defaults[def]; } } } /** * Compiles the template * * @private */ function compileTemplate() { if (!options.template) { // Cache compiled templates if (!app._compiledTemplates.tourguide) { app._compiledTemplates.tourguide = t7.compile(defaultTourGuideTemplate); } template = app._compiledTemplates.tourguide; } else { template = t7.compile(options.template); } } self.prepareSteps = function () { for (var step in tourSteps) { var context = {}; if (tourSteps[step].header) { context.header = tourSteps[step].header; } if (tourSteps[step].message) { context.message = tourSteps[step].message; } if (options.previousButton && step > 0) { options.enablePreviousButton = true; } if (+step === tourSteps.length-1) { options.lastStep = true; } context.options = options; try { tourSteps[step].html = template(context); } catch (TemplateNotDefinedException) { console.log('Failed to compile template with context'); console.log(TemplateNotDefinedException); } } }; /** * Initialize the instance * * @method init */ (function () { // define default template setDefaultTemplate(); // Compile template compileTemplate(); // apply options applyOptions(); // Prepare steps self.prepareSteps(); // set move forward action self.setMoveForwardAction(); // set move backwards action self.setMoveBackwardAction(); }()); // Return instance return self; }; app.tourguide = function (tourSteps, options, currentStep) { return new TourGuide(tourSteps, options, currentStep); }; };