bootstrap-tour icon indicating copy to clipboard operation
bootstrap-tour copied to clipboard

Allow element to reference an element

Open ghost opened this issue 7 years ago • 4 comments

I'm using TypeScript to create Angular 4 directives for Tour.

Here is my code:

import { Attribute, ContentChildren, Directive, ElementRef, QueryList } from '@angular/core';

import Tour from 'bootstrap-tour';

@Directive( {
	selector: '[tour]'
} )
export class TourDirective {
	public constructor(
		public readonly elementRef: ElementRef
	) {}

	@Attribute( 'tourTitle' )
	public title: string;

	@Attribute( 'tour' )
	public text: string;
}

@Directive( {
	selector: '[tourRoot]'
} )
export class TourRootDirective {
	@ContentChildren(TourDirective)
	public tourDirectives: QueryList<TourDirective>;

	private tour: any;

	public ngAfterContentInit() {
		this.tour = new Tour( {
			steps: this.tourDirectives.map( m => ( {
				element: m.elementRef.nativeElement,
				title: m.title,
				content: m.text
			} ) )
		} );
		this.tour.init();
		this.tour.start();
	}
}

The idea is that you have a view like this:

<div tourRoot>
  <div tourTitle="Step 1" tour="This is step 1.">Step 1</div>
  <div tourTitle="Step 2" tour="This is step 2.">Step 2</div>
  <div tourTitle="Step 3" tour="This is step 3.">Step 3</div>
</div>

My code seems to be working, but Popover complains that the element property is not a selector. Using a selector is not an option here, because I can't find a selector that uniquely identifies each child element given that the HTML is determined by the view.

The error I get is

ERROR Error: TOOLTIP: Option "selector" provided type "element" but expected type "(string|boolean)".
    at Object.typeCheckConfig (main.js:51001)
    at Popover._getConfig (main.js:54341)
    at Popover.Tooltip (main.js:53917)
    at new Popover (main.js:54536)
    at HTMLDivElement.<anonymous> (main.js:54589)
    at Function.each (main.js:55031)
    at jQuery.fn.init.each (main.js:54826)
    at jQuery.fn.init._jQueryInterface [as popover] (main.js:54580)
    at Tour._showPopover (main.js:112416)
    at showPopoverAndOverlay (main.js:112193)

Would it be possible for the element property of step to accept an HTMLElement in addition to a selector?

ghost avatar Sep 15 '17 05:09 ghost

This issue doesn't have to be related to Angular

I would like to do something like

var tour = new Tour({
    // ...
});
$('.tour-element').each(function () {
    var $this = $(this);
    // ...
    tour.addStep({
        element: $this,
        // ...
    })
});

adigourdi avatar Feb 21 '18 17:02 adigourdi

@adigourdi I stopped trying to make this work months ago. Your suggestion of using a jQuery selector (or any selector) doesn't work for me because there is no particular class name to select on (which is why I mentioned that it was Angular). From your response, it sounds like just wrapping my reference to m.elementRef.nativeElement in a jQuery object would have resolved my issue, but I cannot verify because I stopped using this library.

ghost avatar Feb 21 '18 20:02 ghost

I wasn't proposing a solution for you @errorx666, I'm demonstrating my own issue with the plugin, in the hope that this will get some traction. And I switched to another plugin too (for now)

adigourdi avatar Feb 22 '18 16:02 adigourdi

I got this error too just after upgrading bootstrap from v3.3.7 to v4.x (bootstraptour works fine receiving jquery element selector before upgrade) Because bootstrap is relying on popper.js for its popover component, there have been changes in their codes.

I manage to pinpoint the cause, and you just need to modify the code in bootstrap.js a little bit. At line 2618: from selector: '(string|boolean)', change it to selector: '(string|boolean|element)', and it works fine for me.

Disclaimer: There may be unforeseen side effect and you need to include your modifications to comply with bootstrap license's terms & conditions.

karasuma27 avatar Dec 28 '18 03:12 karasuma27