angular-intro.js icon indicating copy to clipboard operation
angular-intro.js copied to clipboard

introJs doesn't adapt to elements

Open Hypercubed opened this issue 10 years ago • 15 comments

Not sure if this is a angular-intro.js problem per se... but definitely more relevant to the dynamic nature of angular.

I have an intro that instructs the user to interact with the webpage in a few places. For example, in one case the user clicks on a button, triggering an ng-click, that adds a new html element it the page (inside an ng-repeat). Later in the introduction steps I refer to the new element. However, because this element did not exist when the intro was started if does not point to the current element. IntroJS appears to create references to the elements at start (https://github.com/usablica/intro.js/blob/master/intro.js#L95). I got around this by adding the following onbeforechange callback:

    $scope.introChange = function() {
      var intro = this;

      for (var i = intro._currentStep+1; i < this._options.steps.length; i++) {
        var currentItem = intro._introItems[i];
        var step = intro._options.steps[i];
        if (step.element) {
          currentItem.element = document.querySelector(step.element);
          currentItem.position = step.position;
        }
      }

    };

I hope this helps others or maybe should be an optional part of angular-intro.js.

Hypercubed avatar Mar 01 '15 13:03 Hypercubed

I was able to solve this issue by putting the directive in the parent index.html file and using the CallMe() callback

directive

<div ng-controller="IntroController">
    <div ng-intro-options="IntroOptions"  ng-intro-method="CallMe"
         ng-intro-autostart="ShouldAutoStart"
         ng-intro-autorefresh="true"></div>
    <div ng-view id='introStep-2'></div>
</div>

end of controller

$scope.ShouldAutoStart = false;
$timeout(function(){$scope.CallMe()},1000);

CrouseMatthew avatar Apr 21 '15 17:04 CrouseMatthew

Sure, but does this work if the DOM changes in the middle of the intro, say due to user interaction?

Hypercubed avatar Apr 22 '15 01:04 Hypercubed

^ - We need a fix for this

kmgilbert100 avatar Dec 02 '15 23:12 kmgilbert100

+1

shyamal890 avatar Jan 23 '16 17:01 shyamal890

+1

tucu-man avatar Apr 11 '16 11:04 tucu-man

+1

Muskos avatar Sep 12 '16 14:09 Muskos

+1

chedched avatar Nov 13 '16 00:11 chedched

+1

miliare avatar Nov 16 '16 18:11 miliare

+1

mattifh avatar Jan 08 '17 23:01 mattifh

+1

ZhouQunying avatar Feb 13 '17 01:02 ZhouQunying

+1

Thanks Hypercubed, this solved my issue.

I couldn't override the higher level onbeforechange callback because I was already overriding it on the step level. What worked for me was invoking this function on the onafterchange of the PRECEEDING step to ensure the target element existed on the following step.

leepy82 avatar Feb 13 '17 17:02 leepy82

i don't know if everyone could get this work properly.

when the user interacts with something that will update the view, inside a $timeout, you may call the refresh function, that will re-evaluate queryselector. Now if you still need to work around with onBefore or onAfterchange, i don't think it's the best solutions for us.

A way to properly fix that, it's to rebind the clicks that happens on introjs, into the controller or service, then we'll make the changes that we need and after that we call ngIntroService.next().

if there's anyone in need i may provide that fix, just let me know.

millerscout avatar Mar 04 '17 04:03 millerscout

@millerscout Yeah that solution would be really helpful, especially on multi-component views.

kowsheek avatar Jun 30 '17 04:06 kowsheek

El problema es causado ya que el elemento que se pretende referenciar aun no esta creado.

para eso debemos usar la function

$scope.createIntro = function(){
	var IntroOptions = {
		steps:[
			{
				intro: "first msg",
				position: 'auto'
			},
			{
				element: document.querySelector('#btn_step1'),
				intro: "Hello !",
				position: 'left'
			}
		],
		showStepNumbers: false,
		doneLabel:'Done',
		nextLabel:'Next',
		prevLabel:'Previous'
	};

	ngIntroService.setOptions(IntroOptions);      
	ngIntroService.start();

	ngIntroService.onComplete(function(){
		console.info("complete")
	})

	ngIntroService.onChange(function(targetElement){
		console.info(targetElement.id + " change")
	})
}

setTimeout(function(){ $scope.createIntro(); }, 1000);

emecamila avatar Apr 20 '18 16:04 emecamila

i don't know if everyone could get this work properly.

when the user interacts with something that will update the view, inside a $timeout, you may call the refresh function, that will re-evaluate queryselector. Now if you still need to work around with onBefore or onAfterchange, i don't think it's the best solutions for us.

A way to properly fix that, it's to rebind the clicks that happens on introjs, into the controller or service, then we'll make the changes that we need and after that we call ngIntroService.next().

if there's anyone in need i may provide that fix, just let me know.

HI Millerscout, Please provide this fix for me.

avinash03031991 avatar Dec 02 '18 05:12 avinash03031991