Wait for a Save
Use this when the click is not the end of it: a save, an upload or a request has to finish before the next step makes sense. The step waits for your app, shows a done state, then moves on.
Profile
const driverObj = driver({
showButtons: ["next", "close"],
steps: [
{
element: "#save",
advanceDelay: 600,
onHighlighted: (element, step, { signal, driver }) => {
window.addEventListener(
"profile-saved",
() => driver.advance(),
{ signal }
);
},
popover: {
title: "Save your profile",
instruction: "Click <b>Save</b>.",
},
},
{
element: "#saved",
popover: { title: "Saved", showButtons: ["next"] },
},
],
});
driverObj.drive();Your app fires the event when the request comes back:
async function saveProfile(profile) {
await fetch("/api/profile", {
method: "POST",
body: JSON.stringify(profile),
});
window.dispatchEvent(new Event("profile-saved"));
}
advance()completes the step as if the user did it. WithadvanceDelay, the instruction turns green for the pause first.onHighlightedgets asignalthat aborts when the step is left, so the listener removes itself.
When Next Does the Work
To load something before the next step, take over the Next button with onNextClick and call moveNext() when you’re ready. updatePopover() shows that it’s loading in the meantime.
ReportsNot loaded yet.
const driverObj = driver({
steps: [
{
element: "#reports",
popover: {
title: "Your weekly report",
description: "Next loads the report first.",
onNextClick: async () => {
driverObj.updatePopover({
nextBtnText: "Loading…",
disableButtons: ["next"],
});
await loadReport();
driverObj.moveNext();
},
},
},
{
element: "#report",
popover: { title: "Here it is" },
onDeselected: () => unloadReport(),
},
],
});onNextClick replaces the button’s default action, so the tour only moves when you call moveNext(). onPrevClick works the same way for going back.
Uses: advance(), advanceDelay, onHighlighted, onNextClick, updatePopover()
driver.js