Survey with Vue.js that can navigate using the browser's back and forward buttons

I am currently using Vue.js to develop a survey with multiple pages and everything is functioning properly. However, I am facing an issue where I need the browser's back/forward buttons to perform the same actions as the Previous/Next buttons on the page.

I have searched online several times but have not been able to find a solution yet...

I am aware that I can utilize vue-router for this purpose, but I am unsure of how to implement it.

Could someone guide me on how to achieve this?

HTML

<!DOCTYPE html>
        ***head***

        <body>
            <div id="app">
                <h1>{{ survey.title }}</h1>

                <div id="survey" v-for="(question, index) in survey.questions">

                    <div v-show="index === questionIndex">
                        <h3>{{ question.text }}</h3>
                        <div v-if="questionIndex === 2">
                            <input type="text" v-model="userResponses[2]" placeholder="Please enter your location:"> 
                        </div>
                        <div v-else-if="questionIndex === 4">
                            <select v-model="question4" multiple>
                                <option v-for="response in question.responses"> {{ response.text }} </option></select>
                        </div>
                        <div v-else-if="questionIndex === 5">
                            <select v-model="question5" multiple>
                                <option v-for="response in question.responses"> {{ response.text }} </option></select>
                        </div>
                        <div v-else>
                            <ol>
                                <li v-for="response in question.responses">
                                    <label>
                                        <input type="radio" v-bind:value="response" 
                                                v-bind:name="index" 
                                                v-model="userResponses[index]"> {{ response.text }}
                                    </label>
                                </li>
                            </ol>
                        </div>
                        <div id="container">
                            <button id="left" v-if="questionIndex > 0" v-on:click="prev">Previous</button>
                            <button id="right" v-on:click="next">Next</button>
                        </div>
                    </div>
                </div>
                <div v-show="questionIndex === survey.questions.length">
                    <h2>Thank you for taking our survey!</h2>
                    <p>{{ userResponses }}</p>
                    <p>{{ question4 }}</p>
                    <p>{{ question5 }}</p>
                </div>
            </div>

            <footer>&copy; 2018 George Salukvadze for ***</footer>
        </body>
    </html>
    

Vue.js

window.onload = survey;
        function survey(){
        var survey = {
            title: 'Welcome to online survey for Liquid!',
            questions: [
                {
                    text: "What is your age group?",
                    responses: [
                        {text: '15-24'}, 
                        {text: '25-34'},
                        {text: '35-44'},
                    ]
                }, {
                    text: "What is your gender?",
                    responses: [
                        {text: 'Male'}, 
                        {text: 'Female'},
                        {text: 'Do not identify'},
                    ]
                }, {
                    text: "Where do you live?",
                    responses: [
                        {text: 'Please enter your location'},
                    ]
                }, {
                    text: "Do you like to shop?",
                    responses: [
                        {text: 'Yes'},
                        {text: 'No'},
                    ]
                }, {
                    text: "Select your favorite things to buy:",
                    responses: [
                        {text: 'Clothing'},
                        {text: 'Lingerie'},
                        {text: 'Shoes'},
                        {text: 'Devices'},
                        {text: 'Cars'},
                    ]
                }, {
                    text: "Please select your favorite brands:",
                    responses: [
                        {text: 'Sandro'},
                        {text: 'Maje'},
                        {text: 'Sony'},
                        {text: 'Ferrari'},
                        {text: 'BMW'},
                        {text: 'Asus'},
                    ]
                }
            ]
            };

            new Vue({
                el: '#app',
                data: { 
                    survey: survey,
                    questionIndex: 0,
                    userResponses: Array(survey.questions.length),
                    question4: Array(5),
                    question5: Array(9),
                }, 
                methods: {
                    next: function() {
                        this.questionIndex++;
                    },
                    prev: function() {
                        this.questionIndex--;
                    }
                }
            });
        }
    

Answer №1

To solve the issue at hand, you can utilize the vue-router or opt for a more straightforward approach by leveraging the browser's history API. Here is a step-by-step guide:

  • For navigating between previous and next questions, employ history.pushState to append a state to the browser's history:

     methods: {
         next: function() {
             this.questionIndex++;
             this.updateHistory();  // include this line
         },
         prev: function() {
             this.questionIndex--;
             this.updateHistory();  // include this line
         },
         updateHistory: function() {  // add this method
             history.pushState({questionIndex: this.questionIndex}, "Question " + this.questionIndex);
         }
     }
    
  • Furthermore, monitor these changes in history state. One effective way is to set up a listener within the mounted hook:

     mounted: function() {
         var vm = this;
         window.addEventListener('popstate', function(event) {
             vm.questionIndex = (event.state || {questionIndex: 0}).questionIndex;
         });
     },
    

With that said, you're good to go.

Explore a demonstration page on JSBin (observe the history button).

The source code for the demo is available here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The JQuery datepicker fails to retain the date that is selected

I have a project built with Cakephp 3.6 running locally on my localhost and also deployed on a server. In this project, I am utilizing a datepicker widget as shown below: <?php echo $this->Form->control('created', ['type' ...

Get the maximum width in pixels through JavaScript when it is specified in different units within the CSS

I'm looking to retrieve the max-width value in px from CSS for use in a JavaScript code. The challenge is that this value might be specified in different units in the CSS file. Any suggestions on how to achieve this using JavaScript? const element = ...

Mapping distinct JSON keys to button components using Javascript/React

I am dealing with the JSON data below: [ {"location":"2034","type":"Residential","price":400000,"address":"123 Fake Street","suburb":"Maroubra","historical_DAs&q ...

javascript loop that runs on every second element only

After completing an ajax query, the following JavaScript code is executed. All of my images are named "pic". <script type="text/javascript> function done() { var e = document.getElementsByName("pic"); alert(e.length); for (var i = 0; ...

Learn how to display separate paragraphs upon clicking a specific item

New to coding and eager to learn, I have recently started exploring HTML, CSS, and basic JavaScript. In my journey to enhance my skills, I am working on building a website for practice. One particular page of the site showcases various articles, each acc ...

The functionality of filtering a list based on the selected value from a drop-down menu is malfunctioning

When the page initially loads, there is a dropdown with the default placeholder "Select Person Type" and a checkbox list displaying all persons by default. An angular filter is used to display only the selected type of persons from the dropdown (working p ...

Eliminate redundant tags using jQuery

I have a code snippet that I need help with. I want to check for duplicates and if found, display an alert stating that it already exists so users can't insert the same word/tag again. Can someone please assist me? <div id="tags"> <span>a ...

Fetching properties from an array of components

Hello, I'm currently working on a React component and facing an interesting challenge. Let's say I have an array structured like this: let data: {title: ReactNode}[] = [ {title: "test1"}, {title: <Component1 title="test2& ...

Retrieve JSON information from a web-based service in order to create a stunning photo collection

Is there a web-service accessible at ?limit=12&skip=0 I am looking to retrieve the information from this service and store it in a Javascript array. After some research, I believe I should start with the following code snippet: $.ajax({ type: " ...

The Vue devServer proxy doesn't seem to be resolving the CORS error issue for me

Currently on @vue/cli 3.x and I've set up my vue.config.js with the following: devServer: { proxy: { "/api": { ws: true, changeOrigin: true, target: "http://localhost:8080" } } } Despite th ...

Alert! Server node encountered an issue while handling the response: process.nextTick(function(){throw err;});

Currently, I am working on a simple application to familiarize myself with Mongo, Express, and Node. An issue arises when I attempt to utilize res.json(docs) in the success conditional during the GET request, generating an error process.nextTick(function( ...

Drawing a point on a line within an HTML canvas

Currently, I am in need of a Canvas Path Script that can provide me with points on a line based on percentages. For instance, at 50%, I would like to get the point that represents half of the line, and at 75%, I want to find the point that is 3/4 along the ...

Steps for passing a Javascript variable through POST method and then redirecting to a different page

I am facing an issue with sending a JavaScript variable via POST to a PHP page and displaying the new page. Despite checking the variable using Wireshark and confirming that it is sent correctly (key and value), the new page does not show anything. $(docu ...

What is the best way to merge two values from child components using an event?

I'm having trouble assigning data from a child component. My goal is to follow the example of emitting a specific value with an event The child component code is as follows: <template> <StackLayout orientation="vertical" widt ...

What is the best way to direct attention to the HTML5 canvas element?

I'm having an issue with the HTML5 <canvas> element in Firefox 2.0.0.16 and Safari 3.1.2 on my iMac. Even testing in Firefox 3.0 on Windows did not resolve the problem. Here is the code snippet that seems to be causing the trouble: <td> ...

Can halting an ajax function mid-process prevent it from finishing?

My objective is to convert a video using ffmpeg, which tends to take a considerable amount of time to complete. I'm considering sending an ajax request to the server for this task, but I don't want the user to have to wait until the video convers ...

Is there a way to fetch a random record from a MongoDb collection and exhibit all the fields of that haphazardly chosen document in HTML?

In my current project, I am fetching a random document from a MongoDB Collection and attempting to showcase all the fields of that document in HTML. Although I can successfully retrieve a random document, the issue arises when trying to display its fields ...

Extract the element when the mouse is clicked

I'm currently working on developing a Chrome extension with a specific goal in mind: My aim is to capture the username when a user Ctrl-clicks on a username while browsing Reddit, and then transfer that username from the content script page to the ba ...

Exploring ways to retrieve complete HTML content from a Single Page Application using AJAX?

Seeking assistance in obtaining the complete HTML generated by a Single Page Application built on AngularJS. $.get('http://localhost:3388/' + d.response.path, function (d) { $('#templateContainer').html(d); ...

Develop a fresh Typescript-driven sql.js database

I'm in the process of converting my JavaScript code to TypeScript. One of the libraries I rely on is sql.js. I have successfully installed the corresponding typing for it, but I am facing a roadblock when it comes to creating the database. Here is ho ...