<!DOCTYPE HTML>
<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="author" content="Mauricio Lauffer">
  <title>OpenUI5 - Tour</title>
  <script type="text/javascript" id="sap-ui-bootstrap"
          src="https://openui5.hana.ondemand.com/1.50.5/resources/sap-ui-core.js"
          data-sap-ui-libs="sap.m"
          data-sap-ui-theme="sap_belize"
          data-sap-ui-compatVersion="edge" data-sap-ui-preload="async"
          data-sap-ui-resourceroots='{
          "mlauffer.demo.openui5.tour": "./",
          "openui5.tour": "./resources/openui5/tour"}'></script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
<script type="text/javascript">
  sap.ui.getCore().attachInit(
    function() {
      "use strict";
      sap.ui.require([
        "sap/m/Shell",
        "sap/ui/core/ComponentContainer"
      ], function (Shell, ComponentContainer) {
        sap.ui.component({
          name: "mlauffer.demo.openui5.tour",
          manifest: true,
          async: true
        }).then(function(oComponent) {
          new Shell({
            app: new ComponentContainer({
              height: "100%",
              component: oComponent
            }),
          }).placeAt("content");
        });
      });
    });
</script>
</body>
</html>
# openui5-tour
An OpenUI5 Control which helps developers to create a step-by-step guided tour through their UI5 apps.
OpenUI5 Tour enables an user-friendly way to showcase products and features in your website.


https://github.com/mauriciolauffer/openui5-tour
sap.ui.define([
  'sap/ui/core/UIComponent'
], function(UIComponent) {
  'use strict';

  return UIComponent.extend('mlauffer.demo.openui5.tour.Component', {
    metadata: {
      manifest: 'json'
    },

    init: function () {
      UIComponent.prototype.init.apply(this, arguments);
    },

    destroy: function() {
      UIComponent.prototype.destroy.apply(this, arguments);
    }
  });
});
sap.ui.define([
  'sap/m/Button',
  'sap/m/PlacementType',
  'sap/m/Text',
  'sap/ui/core/mvc/Controller',
  'openui5/tour/Tour',
  'openui5/tour/TourStep'
], function(Button, PlacementType, Text, Controller, Tour, TourStep) {
  'use strict';

  return Controller.extend('mlauffer.demo.openui5.tour.controller.App', {
    _tour: null,

    onInit: function() {
      const tourSteps = [
        new TourStep({
          content: new Text({ text: 'Hey! It is a tour!' }),
          target: this.getView().byId('panel2'),
          title: 'Tour test step1...'
        }),

        new TourStep({
          content: new Button({ text: 'Hey! It is a tour!' }),
          target: this.getView().byId('panel4'),
          title: 'Tour test step2...'
        }),

        new TourStep({
          content: new Text({ text: 'Hey! It is a tour!' }),
          target: this.getView().byId('title3'),
          title: 'Tour test step3...',
          placement: PlacementType.Right
        }),

        new TourStep({
          content: new Button({ text: 'Hey! It is a tour!' }),
          target: this.getView().byId('panel5'),
          title: 'Tour test step4...',
          placement: PlacementType.Top
        }),

        new TourStep({
          content: new Text({ text: 'Hey! It is a tour!' }),
          target: this.getView().byId('panel1'),
          title: 'Tour test step5...'
        })
      ];

      this._tour = new Tour({
        steps: tourSteps,
        started: function() {console.dir('Tour has started...');},
        completed: function(){console.dir('Tour has ended...');},
        nextStep: function(){console.dir('next step called from tour...');},
        previousStep: function(){console.dir('previous step called from tour...');}
      });
    },

    onStartTour: function() {
      this._tour.start();
    }
  });
});
TITLE=OpenUI5 Tour
START=Start Tour
{
	"sap.app": {
		"id": "mlauffer.demo.openui5.tour",
		"type": "application"
	},
	"sap.ui5": {
		"dependencies": {
			"libs": {
				"sap.ui.core": {},
				"sap.m": {},
        "openui5.tour": {}
			}
		},
		"models": {
			"i18n": {
				"type": "sap.ui.model.resource.ResourceModel",
				"settings": {
					"bundleName": "mlauffer.demo.openui5.tour.i18n.i18n"
				}
			}
		},
		"rootView": {
			"viewName": "mlauffer.demo.openui5.tour.view.App",
			"id": "rootApp",
			"type": "XML"
		}
	}
}
jQuery.sap.registerPreloadedModules({
	"version": "2.0",
	"name": "openui5.tour.library-preload",
	"modules": {
		"openui5/tour/library.js": "sap.ui.define([],function(){\"use strict\";return sap.ui.getCore().initLibrary({name:\"openui5.tour\",dependencies:[\"sap.ui.core\",\"sap.m\"],controls:[\"openui5.tour.Tour\",\"openui5.tour.TourStep\"],noLibraryCSS:!0,version:\"${version}\"})});",
		"openui5/tour/Tour.js": "sap.ui.define([\"sap/m/ResponsivePopover\",\"sap/ui/core/Control\"],function(t,e){\"use strict\";var p=e.extend(\"openui5.tour.Tour\",{metadata:{library:\"openui5.tour\",properties:{},defaultAggregation:\"steps\",aggregations:{steps:{type:\"openui5.tour.TourStep\",multiple:!0,singularName:\"step\"}},events:{started:{parameters:{}},completed:{parameters:{}},nextStep:{parameters:{}},previousStep:{parameters:{}}}}});return p.prototype.init=function(){this._currentStepIndex=0},p.prototype.start=function(){this._setFirstStep(),this._setLastStep(),this._setCurrentStepIndex(0),this._goToStep(this._getCurrentStepIndex()),this.fireStarted()},p.prototype.complete=function(){this.getSteps()[this._getCurrentStepIndex()].close(),this._setCurrentStepIndex(0),this.fireCompleted()},p.prototype.nextStep=function(){var t=this._getCurrentStepIndex()+1;this._goToStep(t),this.fireNextStep()},p.prototype.previousStep=function(){var t=this._getCurrentStepIndex()-1;this._goToStep(t),this.firePreviousStep()},p.prototype._getCurrentStepIndex=function(){return this._currentStepIndex},p.prototype._setCurrentStepIndex=function(t){this._currentStepIndex=t},p.prototype._isValidStepIndex=function(t){if(!this.getSteps()[t])throw new Error(\"Tour does not contain step index #\"+t);return!0},p.prototype._goToStep=function(t){this._isValidStepIndex(t)&&(this.getSteps()[this._getCurrentStepIndex()].close(),this._setCurrentStepIndex(t),this.getSteps()[t].open())},p.prototype._setFirstStep=function(){this._isValidStepIndex(0)&&this.getSteps()[0].setIsFirstStep(!0)},p.prototype._setLastStep=function(){var t=this.getSteps().length-1;this._isValidStepIndex(t)&&this.getSteps()[t].setIsLastStep(!0)},p});",
		"openui5/tour/TourStep.js": "sap.ui.define([\"sap/m/Button\",\"sap/m/ButtonType\",\"sap/m/PlacementType\",\"sap/m/ResponsivePopover\",\"sap/ui/core/Control\"],function(t,e,o,i,n){\"use strict\";var p=n.extend(\"openui5.tour.TourStep\",{metadata:{library:\"openui5.tour\",properties:{title:{type:\"string\",group:\"Appearance\",defaultValue:\"\"},icon:{type:\"sap.ui.core.URI\",group:\"Appearance\",defaultValue:\"\"},target:{type:\"sap.ui.core.Control\",group:\"Behavior\",defaultValue:\"\"},placement:{type:\"sap.m.PlacementType\",group:\"Behavior\",defaultValue:o.PreferredTopOrFlip}},defaultAggregation:\"content\",aggregations:{content:{type:\"sap.ui.core.Control\",multiple:!1},_popup:{type:\"sap.ui.core.Control\",multiple:!1,visibility:\"hidden\"}}}});return p.prototype.init=function(){this.setIsFirstStep(!1),this.setIsLastStep(!1)},p.prototype.exit=function(){},p.prototype.open=function(){if(!this.getTarget())throw new Error(\"The step you are trying to open has no target assigned.\");this.getAggregation(\"_popup\")||this.setAggregation(\"_popup\",this._getPopup()),this.getTarget().getDomRef().scrollIntoView(),this.getAggregation(\"_popup\").openBy(this.getTarget())},p.prototype.close=function(){this.getAggregation(\"_popup\")&&this.getAggregation(\"_popup\").isOpen()&&this.getAggregation(\"_popup\").close()},p.prototype.setIsFirstStep=function(t){this._isFirstStep=t},p.prototype.setIsLastStep=function(t){this._isLastStep=t},p.prototype._setFirstStep=function(t){t.getBeginButton().setEnabled(!1)},p.prototype._setLastStep=function(t){this._setFinishButton(t)},p.prototype._getPopup=function(){this.getContent()&&this.getContent().addStyleClass(\"sapUiSmallMargin\");var t=this._createPopup(this.getId(),this.getPlacement(),this.getTitle(),this.getIcon(),this.getContent());return this._setPreviousButton(t),this._isFirstStep&&this._setFirstStep(t),this._isLastStep?this._setLastStep(t):this._setNextButton(t),t},p.prototype._setFinishButton=function(t){var o=this._createFinishButton(t.getId(),this._finishStep.bind(this));t.setEndButton(o),o.setType(e.Emphasized)},p.prototype._setNextButton=function(t){var o=this._createNextButton(t.getId(),this._nextStep.bind(this));t.setEndButton(o),o.setType(e.Emphasized)},p.prototype._setPreviousButton=function(t){var e=this._createPreviousButton(t.getId(),this._previousStep.bind(this));t.setBeginButton(e)},p.prototype._createPopup=function(t,e,o,n,p){return new i(t+\"-popover\",{modal:!0,placement:e,title:o,icon:n,content:p})},p.prototype._createFinishButton=function(e,o){return new t(e+\"-finishButton\",{icon:\"sap-icon://accept\",text:\"Done\",press:o})},p.prototype._createNextButton=function(e,o){return new t(e+\"-nextButton\",{icon:\"sap-icon://open-command-field\",text:\"Next\",press:o})},p.prototype._createPreviousButton=function(e,o){return new t(e+\"-previousButton\",{icon:\"sap-icon://close-command-field\",text:\"Back\",press:o})},p.prototype._nextStep=function(){this.getParent().nextStep()},p.prototype._previousStep=function(){this.getParent().previousStep()},p.prototype._finishStep=function(){this.getParent().complete()},p});"
	}
});
<mvc:View controllerName="mlauffer.demo.openui5.tour.controller.App" displayBlock="true"
          xmlns:mvc="sap.ui.core.mvc"
          xmlns="sap.m">
    <App>
        <Page id="page" title="{i18n>TITLE}">
            <Panel id="panel1" height="300px">
                <Title text="Panel 1" />
            </Panel>
            <Panel id="panel2" height="300px">
                <Title text="Panel 2" />
            </Panel>
            <Panel id="panel3" height="300px">
                <Title id="title3" text="Panel 3" />
            </Panel>
            <Panel id="panel4" height="300px">
                <Title text="Panel 4" />
            </Panel>
            <Panel id="panel5" height="300px">
                <Title text="Panel 5" />
            </Panel>
            <footer>
                <Toolbar>
                    <ToolbarSpacer />
                    <Button icon="sap-icon://begin" text="{i18n>START}" press="onStartTour" />
                </Toolbar>
            </footer>
        </Page>
    </App>
</mvc:View>