diff --git a/README.md b/README.md index 053d6f0..528dac6 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ ngOnboarding is a tooltip tutorial / onboarding framework for [Angular.js](http: This library requires Angular.js 1.2 or greater along with any recent version of jQuery. +## Installation + +```bash +npm install ng-onboarding +``` + ## Demo You can find a very simple example of ngOnboarding [here](http://adamalbrecht.github.io/ngOnboarding/). @@ -66,11 +72,11 @@ There are a number of options that can be passed to each step in your on-boardin | width | null | Width of the popover. Defaults to the width of the content. | | height | null | Height of the popover. Defaults to the height of the content. | | top, right, bottom, left | null | Set the positioning of the popover explicitly. -| height | null | Height of the popover. Defaults to the height of the content. | | xOffset | null | Offset the horizontal position of the popover relative to the attached element. | | yOffset | null | Offset the vertical position of the popover relative to the attached element. | + ## Overriding Directive Defaults You can also pre-configure some options during your app's configuration phase. @@ -91,6 +97,8 @@ app.config(function(ngOnboardingDefaultsProvider) { | showDoneButton | true | Show a 'Done' button on the last popover | | showStepInfo | true | Shows 'Step X of Y' text on each popover | | closeButtonText | X | Text/HTML used for the close button | +| actualStepText | 'Step' | Text previous the actual step | +| totalStepText | 'of' | Text between actual step and total steps | The CSS classes used in the HTML are also configurable. Please see the source for more info. diff --git a/dist/ng-onboarding.js b/dist/ng-onboarding.js index 52b74a4..dd458fe 100644 --- a/dist/ng-onboarding.js +++ b/dist/ng-onboarding.js @@ -23,6 +23,8 @@ closeButtonClass: 'onboarding-close-button', closeButtonText: 'X', stepClass: 'onboarding-step-info', + actualStepText: 'Step', + totalStepText: 'of', showStepInfo: true }, $get: function() { @@ -59,7 +61,6 @@ var attributesToClear, curStep, setupOverlay, setupPositioning; curStep = null; attributesToClear = ['title', 'top', 'right', 'bottom', 'left', 'width', 'height', 'position']; - scope.stepCount = scope.steps.length; scope.next = function() { return scope.index = scope.index + 1; }; @@ -73,9 +74,9 @@ return scope.onFinishCallback(); } }; - scope.$watch('index', function(newVal, oldVal) { + scope.$watchGroup(['index', 'enabled'], function(newVals, oldVal) { var attr, k, v, _i, _len; - if (newVal === null) { + if (typeof newVals[0] === 'undefined') { scope.enabled = false; setupOverlay(false); return; @@ -84,6 +85,7 @@ scope.lastStep = scope.index + 1 === scope.steps.length; scope.showNextButton = scope.index + 1 < scope.steps.length; scope.showPreviousButton = scope.index > 0; + scope.stepCount = scope.steps.length; for (_i = 0, _len = attributesToClear.length; _i < _len; _i++) { attr = attributesToClear[_i]; scope[attr] = null; @@ -103,6 +105,8 @@ scope.previousButtonText = $sce.trustAsHtml(scope.previousButtonText); scope.doneButtonText = $sce.trustAsHtml(scope.doneButtonText); scope.closeButtonText = $sce.trustAsHtml(scope.closeButtonText); + scope.actualStepText = $sce.trustAsHtml(scope.actualStepText); + scope.totalStepText = $sce.trustAsHtml(scope.totalStepText); setupOverlay(); return setupPositioning(); }); @@ -112,7 +116,7 @@ } $('.onboarding-focus').removeClass('onboarding-focus'); if (showOverlay) { - if (curStep['attachTo'] && scope.overlay) { + if (curStep['attachTo'] && scope.overlay && scope.enabled) { return $(curStep['attachTo']).addClass('onboarding-focus'); } } @@ -177,7 +181,7 @@ return scope.index = 0; } }, - template: "
\n
\n
\n
\n

\n \n
\n

\n
\n
\n Step {{index + 1}} of {{stepCount}}\n \n \n \n
\n
\n
" + template: "
\n
\n
\n
\n

\n \n
\n

\n
\n
\n {{actualStepText}} {{index + 1}} {{totalStepText}} {{stepCount}}\n \n \n \n
\n
\n
" }; } ]); diff --git a/dist/ng-onboarding.min.js b/dist/ng-onboarding.min.js index 8897ba1..5c026eb 100644 --- a/dist/ng-onboarding.min.js +++ b/dist/ng-onboarding.min.js @@ -1 +1 @@ -(function(){var a;a=angular.module("ngOnboarding",[]),a.provider("ngOnboardingDefaults",function(){return{options:{overlay:!0,overlayOpacity:.6,overlayClass:"onboarding-overlay",popoverClass:"onboarding-popover",titleClass:"onboarding-popover-title",contentClass:"onboarding-popover-content",arrowClass:"onboarding-arrow",buttonContainerClass:"onboarding-button-container",buttonClass:"onboarding-button",showButtons:!0,nextButtonText:"Next →",previousButtonText:"← Previous",showDoneButton:!0,doneButtonText:"Done",closeButtonClass:"onboarding-close-button",closeButtonText:"X",stepClass:"onboarding-step-info",showStepInfo:!0},$get:function(){return this.options},set:function(a,b){var c,d,e;if("object"==typeof a){e=[];for(c in a)d=a[c],e.push(this.options[c]=d);return e}return this.options[a]=b}}}),a.directive("onboardingPopover",["ngOnboardingDefaults","$sce","$timeout",function(a,b){return{restrict:"E",scope:{enabled:"=",steps:"=",onFinishCallback:"=",index:"=stepIndex"},replace:!0,link:function(c){var d,e,f,g;return e=null,d=["title","top","right","bottom","left","width","height","position"],c.stepCount=c.steps.length,c.next=function(){return c.index=c.index+1},c.previous=function(){return c.index=c.index-1},c.close=function(){return c.enabled=!1,f(!1),c.onFinishCallback?c.onFinishCallback():void 0},c.$watch("index",function(h){var i,j,k,l,m;if(null===h)return c.enabled=!1,void f(!1);for(e=c.steps[c.index],c.lastStep=c.index+1===c.steps.length,c.showNextButton=c.index+10,l=0,m=d.length;m>l;l++)i=d[l],c[i]=null;for(j in a)k=a[j],void 0===e[j]&&(c[j]=k);for(j in e)k=e[j],c[j]=k;return c.description=b.trustAsHtml(c.description),c.nextButtonText=b.trustAsHtml(c.nextButtonText),c.previousButtonText=b.trustAsHtml(c.previousButtonText),c.doneButtonText=b.trustAsHtml(c.doneButtonText),c.closeButtonText=b.trustAsHtml(c.closeButtonText),f(),g()}),f=function(a){return null==a&&(a=!0),$(".onboarding-focus").removeClass("onboarding-focus"),a&&e.attachTo&&c.overlay?$(e.attachTo).addClass("onboarding-focus"):void 0},g=function(){var a,b,d,f,g,h,i;return a=e.attachTo,c.position=e.position,h=15,i=15,a&&(c.left||c.right||(d=null,f=null,"right"===c.position?d=$(a).offset().left+$(a).outerWidth()+h:"left"===c.position?f=$(window).width()-$(a).offset().left+h:("top"===c.position||"bottom"===c.position)&&(d=$(a).offset().left),e.xOffset&&(null!==d&&(d+=e.xOffset),null!==f&&(f-=e.xOffset)),c.left=d,c.right=f),c.top||c.bottom||(g=null,b=null,"left"===c.position||"right"===c.position?g=$(a).offset().top:"bottom"===c.position?g=$(a).offset().top+$(a).outerHeight()+i:"top"===c.position&&(b=$(window).height()-$(a).offset().top+i),e.yOffset&&(null!==g&&(g+=e.yOffset),null!==b&&(b-=e.yOffset)),c.top=g,c.bottom=b)),c.positionClass=c.position&&c.position.length?"onboarding-"+c.position:null},c.steps.length&&!c.index?c.index=0:void 0},template:"
\n
\n
\n
\n

\n \n
\n

\n
\n
\n Step {{index + 1}} of {{stepCount}}\n \n \n \n
\n
\n
"}}])}).call(this); \ No newline at end of file +(function(){var a;a=angular.module("ngOnboarding",[]),a.provider("ngOnboardingDefaults",function(){return{options:{overlay:!0,overlayOpacity:.6,overlayClass:"onboarding-overlay",popoverClass:"onboarding-popover",titleClass:"onboarding-popover-title",contentClass:"onboarding-popover-content",arrowClass:"onboarding-arrow",buttonContainerClass:"onboarding-button-container",buttonClass:"onboarding-button",showButtons:!0,nextButtonText:"Next →",previousButtonText:"← Previous",showDoneButton:!0,doneButtonText:"Done",closeButtonClass:"onboarding-close-button",closeButtonText:"X",stepClass:"onboarding-step-info",actualStepText:"Step",totalStepText:"of",showStepInfo:!0},$get:function(){return this.options},set:function(a,b){var c,d,e;if("object"==typeof a){e=[];for(c in a)d=a[c],e.push(this.options[c]=d);return e}return this.options[a]=b}}}),a.directive("onboardingPopover",["ngOnboardingDefaults","$sce","$timeout",function(a,b,c){return{restrict:"E",scope:{enabled:"=",steps:"=",onFinishCallback:"=",index:"=stepIndex"},replace:!0,link:function(c,d,e){var f,g,h,i;return g=null,f=["title","top","right","bottom","left","width","height","position"],c.next=function(){return c.index=c.index+1},c.previous=function(){return c.index=c.index-1},c.close=function(){return c.enabled=!1,h(!1),c.onFinishCallback?c.onFinishCallback():void 0},c.$watchGroup(["index","enabled"],function(d,e){var j,k,l,m,n;if("undefined"==typeof d[0])return c.enabled=!1,void h(!1);for(g=c.steps[c.index],c.lastStep=c.index+1===c.steps.length,c.showNextButton=c.index+10,c.stepCount=c.steps.length,m=0,n=f.length;n>m;m++)j=f[m],c[j]=null;for(k in a)l=a[k],void 0===g[k]&&(c[k]=l);for(k in g)l=g[k],c[k]=l;return c.description=b.trustAsHtml(c.description),c.nextButtonText=b.trustAsHtml(c.nextButtonText),c.previousButtonText=b.trustAsHtml(c.previousButtonText),c.doneButtonText=b.trustAsHtml(c.doneButtonText),c.closeButtonText=b.trustAsHtml(c.closeButtonText),c.actualStepText=b.trustAsHtml(c.actualStepText),c.totalStepText=b.trustAsHtml(c.totalStepText),h(),i()}),h=function(a){return null==a&&(a=!0),$(".onboarding-focus").removeClass("onboarding-focus"),a&&g.attachTo&&c.overlay&&c.enabled?$(g.attachTo).addClass("onboarding-focus"):void 0},i=function(){var a,b,d,e,f,h,i;return a=g.attachTo,c.position=g.position,h=15,i=15,a&&(c.left||c.right||(d=null,e=null,"right"===c.position?d=$(a).offset().left+$(a).outerWidth()+h:"left"===c.position?e=$(window).width()-$(a).offset().left+h:("top"===c.position||"bottom"===c.position)&&(d=$(a).offset().left),g.xOffset&&(null!==d&&(d+=g.xOffset),null!==e&&(e-=g.xOffset)),c.left=d,c.right=e),c.top||c.bottom||(f=null,b=null,"left"===c.position||"right"===c.position?f=$(a).offset().top:"bottom"===c.position?f=$(a).offset().top+$(a).outerHeight()+i:"top"===c.position&&(b=$(window).height()-$(a).offset().top+i),g.yOffset&&(null!==f&&(f+=g.yOffset),null!==b&&(b-=g.yOffset)),c.top=f,c.bottom=b)),c.position&&c.position.length?c.positionClass="onboarding-"+c.position:c.positionClass=null},c.steps.length&&!c.index?c.index=0:void 0},template:"
\n
\n
\n
\n

\n \n
\n

\n
\n
\n {{actualStepText}} {{index + 1}} {{totalStepText}} {{stepCount}}\n \n \n \n
\n
\n
"}}])}).call(this); \ No newline at end of file diff --git a/index.html b/index.html index 0e747f7..14ce384 100644 --- a/index.html +++ b/index.html @@ -99,7 +99,9 @@

Content Zone 4

overlay: true, title: 'Welcome!', description: "This is a box with the position set to 'centered'.", - position: 'centered' + position: 'centered', + actualStepText: 'Paso', + totalStepText: 'de' }, { attachTo: '#content_1', diff --git a/package.json b/package.json index 39947a6..77a9445 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,10 @@ { - "name": "ngOnboarding", - "version": "0.1.7", + "name": "ng-onboarding", + "version": "0.1.8", + "repository": { + "type": "git", + "url": "https://github.com/adamalbrecht/ngOnboarding" + }, "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-coffee": "~0.7", diff --git a/src/ng-onboarding.coffee b/src/ng-onboarding.coffee index 10e51dd..c3b5877 100644 --- a/src/ng-onboarding.coffee +++ b/src/ng-onboarding.coffee @@ -29,6 +29,8 @@ app.provider "ngOnboardingDefaults", -> closeButtonClass: 'onboarding-close-button', closeButtonText: 'X', stepClass: 'onboarding-step-info', + actualStepText: 'Step', + totalStepText: 'of', showStepInfo: true } $get: -> @@ -53,7 +55,6 @@ app.directive 'onboardingPopover', ['ngOnboardingDefaults', '$sce', '$timeout', # Important Variables curStep = null attributesToClear = ['title', 'top', 'right', 'bottom', 'left', 'width', 'height', 'position'] - scope.stepCount = scope.steps.length # Button Actions scope.next = -> scope.index = scope.index + 1 @@ -65,8 +66,8 @@ app.directive 'onboardingPopover', ['ngOnboardingDefaults', '$sce', '$timeout', scope.onFinishCallback() # Watch for changes in the current step index - scope.$watch 'index', (newVal, oldVal) -> - if newVal == null + scope.$watchGroup ['index','enabled'], (newVals, oldVal) -> + if typeof(newVals[0]) == 'undefined' scope.enabled = false setupOverlay(false) return @@ -75,6 +76,7 @@ app.directive 'onboardingPopover', ['ngOnboardingDefaults', '$sce', '$timeout', scope.lastStep = (scope.index + 1 == scope.steps.length) scope.showNextButton = (scope.index + 1 < scope.steps.length) scope.showPreviousButton = (scope.index > 0) + scope.stepCount = scope.steps.length for attr in attributesToClear scope[attr] = null for k, v of ngOnboardingDefaults @@ -89,13 +91,15 @@ app.directive 'onboardingPopover', ['ngOnboardingDefaults', '$sce', '$timeout', scope.previousButtonText = $sce.trustAsHtml(scope.previousButtonText) scope.doneButtonText = $sce.trustAsHtml(scope.doneButtonText) scope.closeButtonText = $sce.trustAsHtml(scope.closeButtonText) + scope.actualStepText = $sce.trustAsHtml(scope.actualStepText) + scope.totalStepText = $sce.trustAsHtml(scope.totalStepText) setupOverlay() setupPositioning() setupOverlay = (showOverlay=true) -> $('.onboarding-focus').removeClass('onboarding-focus') if showOverlay - if curStep['attachTo'] && scope.overlay + if curStep['attachTo'] && scope.overlay && scope.enabled $(curStep['attachTo']).addClass('onboarding-focus') setupPositioning = -> @@ -130,7 +134,7 @@ app.directive 'onboardingPopover', ['ngOnboardingDefaults', '$sce', '$timeout', top = $(attachTo).offset().top + $(attachTo).outerHeight() + yMargin else if scope.position == 'top' bottom = $(window).height() - $(attachTo).offset().top + yMargin - + if curStep['yOffset'] top = top + curStep['yOffset'] if top != null @@ -157,7 +161,7 @@ app.directive 'onboardingPopover', ['ngOnboardingDefaults', '$sce', '$timeout',

- Step {{index + 1}} of {{stepCount}} + {{actualStepText}} {{index + 1}} {{totalStepText}} {{stepCount}}