Code Monkey home page Code Monkey logo

Comments (10)

luksurious avatar luksurious commented on July 22, 2024 3

As a reference, I am using this structure to work around this limitation:

var waitForElementVisible = function(element, callback) {
    var checkExist = setInterval(function() {
        $element = typeof element == "function" ? $(element()) : $(element);
        if ($element.is(':visible')) {
            clearInterval(checkExist);
            if (typeof callback == "function") {
                callback();
            }
        }
    }, 100);
};

var nextOnCallback = function(callback) {
    var currentStep = window.hopscotch.getCurrStepNum();
    callback(function() {
        window.hopscotch.startTour(theTour, currentStep);
    });
};

var theTour = {
    id: theId,
    steps: [{
        title: 'title',
        content: 'content',
        target: 'target',
        placement: 'bottom',
        onNext: function() {
            $('.ajax-call')[0].click();

            nextOnCallback(function(callback) {
              waitForElementVisible(function() {
                return $('.element-to-wait-for');
              }, callback);
            });
        },
        multipage: true
    }, {
        title: 'title',
        content: 'content',
        target: '.element-to-wait-for',
        placement: 'bottom',
        onPrev: function() {
            window.hopscotch.startTour(theTour, window.hopscotch.getCurrStepNum());
        }
    }]
};

from hopscotch.

kamranayub avatar kamranayub commented on July 22, 2024 1

Yah I'd definitely rather use support for deferred/async to properly await showing.

I would prefer a full lifecycle mechanism, like:

{
  onBeforeShow: function () {
    // void
  },
  waitOnBeforeShow: function () {
    // return a deferred object here
  },
  onAfterShow: function () {
    // void
  },
  canGoNext: function () {
    return true; // return bool
  },
  canGoPrev: function () {
    return false; // return bool
  }
}

This would solve almost all issues regarding waiting for async stuff, doing things before/after showing, and preventing/canceling next/prev actions (even returning true/false for onNext and onPrev to cancel/allow would work).

from hopscotch.

timlindvall avatar timlindvall commented on July 22, 2024

Hmmm... if I'm reading the Hopscotch code correctly, the onNext callback should get invoked before moving on to showing the next step (line 1622 calls the callback, then line 1648 tells the bubble to render itself for the next step). However, there doesn't appear to be any mechanism in place to tell Hopscotch to hold up for asynchronous behaviors, so HopscotchBubble.render() is likely to get invoked before the AJAX call is resolved.

It appears an ongoing theme with the open issues is the necessity to reveal via API a method to tell Hopscotch to recalculate its positioning after the DOM is changed. This could be coupled with a step config option that tells Hopscotch not to render the bubble until it's told to do so (thus your callback would be responsible to call Hopscotch.rerender() once the AJAX call resolves).

In the interim, there's a few (somewhat hacky) options I can think of that might help...

  • Use step.delay to delay the showing of the next step, which will in turn delay the calculation of where the bubble should render. Only problem, though, is that if the AJAX response takes longer than the delay, you'll still end up with an error.
  • Use an element on the page that you know to exist before the AJAX call (maybe the container you're placing your AJAX response content into?).
  • Dunno how well this will work... but try setting the multipage flag on your previous step, then once the content is loaded call hopscotch.startTour() and it might pick up where it left off. This might cause Hopscotch to fire any onStart callbacks again, though.

I hope this helps!

from hopscotch.

timlindvall avatar timlindvall commented on July 22, 2024

Oh crumbs... sorry... the previous comment is inaccurate. Hopscotch doesn't reach line 1622 until after it's determined what the next step should be by querying the step targets. So, given that, only options two and three are still viable, but option two is only viable if the target exists on the page before triggering onNext.

IMO, I don't think this is desired behavior... the docs aren't specific, but I think the general impression is that onNext would trigger first, as an immediate action to clicking the Next button, instead of waiting until we've determined what the next step should be. But, perhaps the original intent is that we shouldn't do anything that might affect the page (things that onNext might carry out) until we've actually determined where we're going next.

I think I'm going to play around with option three (the multipage flag) a bit... if this works as a viable option (after addressing the above), this might be a reasonable path forward for adding this sort of "waiting" functionality to Hopscotch. multipage and waitForAsync could both end up proxying to the same logic internally and hopscotch.rerender() would itself call hopscotch.startTour() or do some other action that reboots the tour from its old state.

Any thoughts? I'm curious to know what everyone's general impressions are around the onNext callback and whether what's described above is in sync with everyone else's use case, or if the "suppress until we've found something relevant" behavior is desired.

from hopscotch.

luksurious avatar luksurious commented on July 22, 2024

I was trying to use hopscotch in a similar scenario, where content is loaded via AJAX, and the tour should target an element from that loaded content.

While the multipage and starting the tour after the elements are visible works, it is not so nice.

Would be great if an async option would be available.

from hopscotch.

gfrobenius avatar gfrobenius commented on July 22, 2024

I need this enhancement as well. In the meantime, thanks for the workaround! It works great.

from hopscotch.

vasvir avatar vasvir commented on July 22, 2024

@kamranayub +1

Vassilis

from hopscotch.

ataft avatar ataft commented on July 22, 2024

+1
I would love onBefore and onAfter events for all actions, next, back, etc.

from hopscotch.

n0nag0n avatar n0nag0n commented on July 22, 2024

Thank you @luksurious Your workaround saved me.

from hopscotch.

halfhp avatar halfhp commented on July 22, 2024

I was able to get the desired effect by returning false from my onNext() callback, after it kicks off the async code to complete before proceeding to step2. (This could be an Ajax request, or whatever)

I then resume the tutorial on step 2 at the end of my async call, since returning false from onNext() ends the tour.

Something like this: (sorry if its messy - i dont work with JS that often)

var myTour = {
    id: "tour",
    steps: [
        {
            title: "Step1",
            content: "This is step1.",
            target: "something",
            multipage: true,
            onNext: function () {
                doSomethingAsyncWithOnCompleteCb(function() {
                    // do some stuff
                    ...
                    // show step2 as soon as the async work concludes:
                    hopscotch.startTour(myTour, 1); // step[1] == "Step2"
                })
                return false;
            }
        },
        {
            title: "Step2",
            content: "Select a repo from the search results.",
            target: "somethingElse"
        }
    ]
};

from hopscotch.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.