Start tutorial after clicked a button that changes view (intro.js)

109 Views Asked by At

I have a side bar that is displayed in all views. In that side bar I have a dropdown menu to select some tours that are made with intro.js. There is a quick start, that works perfect. I want to add some options with the names of the views in the tutorial dropdown so that when I click on it I go to the view and start the tutorial. Important, there is an option to start a tutorial when you enter that view, but I don't want that, because if I access redirected from another part it will always start the tutorial, I want it to start only from the tutorial dropdown menu. The problem I have is that my js function switches me to another view but the tutorial starts and stops from one (it shows a fraction of a second).

This is what i have. The dropdown menu:

<div class="language-selector">
    <!-- Dropdown Trigger -->
    <a id="tutorial" class="dropdown-trigger sidebar-links a" href="#" data-target="tutorialDropdown">
        <span style="display: flex; align-items: center;">
            <i class="fas fa-question-circle"></i>
                {% trans "Tutorial" %}
            <i class="fas fa-caret-down"></i>
        </span>
    </a>    
    <!-- Dropdown Structure -->
    <ul id="tutorialDropdown" class="dropdown-content">
        <li>
            <button class="start-tour-button" onclick="startTourAndRedirect('quick-start', '')">
                Quick Start
            </button>
        </li>
        <li>
            <button class="start-tour-button" onclick="startTourAndRedirect('review-panel', '{% url 'validate' %}')">
                 Review Panel
            </button>
        </li>   
    </ul>
</div>

My js code:

function startTourAndRedirect(tourName, url) {
    if (url !== "") {
        window.location.href = url;
    }

    let steps = [];

    if (tourName == "quick-start") {
        steps = [
            /* steps for quic-start */
        ];
    } else if (tourName == "review-panel") {
        steps = [
            /* steps for review-panel */
        ];
    } 
    console.log(steps);
    if (steps.length > 0) {
        introJs()
            .setOptions({
                steps: steps,
                showProgress: true,
                showBullets: false,
                disableInteraction: true,
            })
            .start();
    }
    else {
        console.log("No steps found");
    }
}
1

There are 1 best solutions below

0
On BEST ANSWER

I solved this, saving in a cookie the selected tour name, and starting the tutorial when the view changes.

<ul id="tutorialDropdown" class="dropdown-content">
    <li>
        <button class="start-tour-button" onclick="setSelectedTour('review-panel', '{% url 'validate' %}')">
        Review Panel
        </button>
    </li>
    <li>
        <button class="start-tour-button" onclick="setSelectedTour('activity-feed', '{% url 'activity_feed' %}')">
        Activity Feed
        </button>
    </li>
</ul>

and the js code:

function setSelectedTour(tourName, url) {
    document.cookie = `selectedTour=${tourName}; expires=; path=/; max-age=3`;
    if (url !== '') {
        window.location.href = url;
    }
}

// Function to get the selected tour name from the cookie
function getSelectedTour() {
    const name = "selectedTour=";
    const cookies = document.cookie.split(';');
    for (let i = 0; i < cookies.length; i++) {
        let cookie = cookies[i].trim();
        if (cookie.indexOf(name) === 0) {
            return cookie.substring(name.length, cookie.length);
        }
    }
    return "";
}

// Function to start the selected tour
function startSelectedTour() {
    const selectedTour = getSelectedTour();
    if (selectedTour) {
        startTour(selectedTour);
    }
}

function startTour(tourName) {
    let jsonData;

    fetch('/config/stepsTours.json')
        .then(response => response.json())
        .then(data => {
            jsonData = data;
            let steps = [];
            // Load steps for the selected tour
            if (tourName == "review-panel" && jsonData["review-panel"]) {
                steps = jsonData["review-panel"];
            } else if (tourName == "activity-feed" && jsonData["activity-feed"]) {
                steps = jsonData["activity-feed"];
            }
            // Start the tutorial
            if (steps.length > 0) {
                const intro = introJs()
                    .setOptions({
                        steps: steps,
                        showProgress: true,
                        showBullets: false,
                        disableInteraction: true,
                    });
                intro.start();
            } else {
                console.log("No steps found");
            }
        })
        .catch(error => console.error('Error loading JSON file:', error));
}

window.addEventListener('load', function () {
    startSelectedTour();
});