benmarch / angular-ui-tour

Product tour using Angular UI Bootstrap Tooltips
163 stars 49 forks source link

Popup not properly sized & positioned #165

Open truonggiangdao opened 6 years ago

truonggiangdao commented 6 years ago

I am using the exact versions of the following:

I have installed this library via: NPM

I have observed the following behavior: I try to show the tour popup after some dynamic content is rendered but the popup is blank and very long. image

This is how I expected it to behave: Showing popup at normal size and correct position

Here is my tour config, and all related step configs:

var tourConfig = {
    backdrop: true,
    appendToBody: true
};
var tour = uiTourService.createDetachedTour("myTour", tourConfig);
tour.createStep({
    selector: '#targetEl',
    stepId: 'step1',
    order: 1,
    title: 'Tips',
    placement: 'top-left',
    templateUrl: "tooltipTemplate.html",
    content: 'A long content for the tip.'
});

tour.start();

Additional notes/code: I think my issue similar to this one: #144 but I already tried:

$timeout(function () {
    tour.reposition();
    $window.scrollTo(0, $window.pageYOffset + 1);
});

I also had to make the fake scroll on window to make the popover auto resize and reposition. But sometime it just doesn't work because the page not long enough to scroll-able.

Also, I think this maybe importance if i change the step placement from "top-left" to "top" or "left" then it works perfectly.

benmarch commented 6 years ago

Hey @truonggiangdao, thank you for all of the information. I have a few questions and suggestions for you, please let me know if any of them help:

truonggiangdao commented 6 years ago

Hi @benmarch thank you for the suggestions. I just did some test and these are the info, I hope they are useful:

So I tried waiting after the dynamic content rendered and call tour.start() and I also set a timeout 5s and make the tour reposition but still the same

tour.start();
$timeout(function () {
    tour.reposition();
    $window.scrollTo(0, $window.pageYOffset + 1);
}, 5000);

I even did a $interval and reposition the tour every 5s but still no luck, I found a few times the popover hidden away and re-appear again on the next interval but still the same long-blank popover.

Also, this is the result when I inspect the popover: image

And again when I try placement "top" instead it show normally image

And also working when tried with all other placements: top, bottom, left, right, bottom-left, top-right ... So only "top-left" produce the issue (But because my site is responsive so i have to go with top-left or some part of the popover will be outside of viewport on mobile) I get that the placement is for the arrow only, but it's a bit weird when only this give the issue

Thanks

benmarch commented 6 years ago

Hey @truonggiangdao, I'm really not sure what would cause the size distortion. I can see from you screenshots that the popover element is registering as being very large, but since the height is not specific in the CSS, it must be coming from a child element. See if you can find the most nested child element that is larger than it is supposed to be.

In the next version, there will be an option to pass constraints to the popover positioning. So you can, for example, set the initial position to "top" and if it bleeds off the viewport it you can tell it to move "left" to stay in the viewport. Unfortunately that might take some time since there is a big backlog for the next release.

oscarmeneses commented 6 years ago

@benmarch I was going to create a new bug report but I believe my issue is similar or related to this one. I added a local hack, while I find more time to review.

RE: You can try to call tour.reposition() in an onShown() handler which executes after the step is shown.

It seems that reposition on the onShown handler doesn't work because the template has not been processed yet. If dimensions for the popup are not explicitly defined, height for example might still be zero. Also, since pop has display:none until showPopup is executed, it affects the positioning (at least in my case) because it has no width/height. This was causing the popup content to show, but in the wrong place.

My local fix was to call step.reposition() within the showpopup timeout

function showPopup(step) {
        //activate Tether
        positionPopup(step);

        //nudge the screen to ensure that Tether is positioned properly
        $window.scrollTo($window.scrollX, $window.scrollY + 1);

        //wait until next digest
        $timeout(function () {
            //show the popup
            step.popup.css({
                visibility: 'visible',
                display: 'block'
            });
            step.reposition(); // local hack to reposition      
            //scroll to popup
            focusPopup(step);
        }, 100); //ensures size and position are correct
    }

I'll review further and provide additional details. Let me know if you prefer for me to create a new issue.

vinaykevadia commented 5 years ago

i fixed as follow

image

image