Survey Vue having trouble with indexing questions

I am in the process of developing a quiz/survey application using vue.js. As someone who is new to vue, I am still learning about its functionalities. The quiz/survey that I am creating will present different questions based on the user's responses to the initial question.

For example, if a user answers "yes", question 2 will be displayed, and if they answer "no", question 3 will be shown.

I am exploring different approaches to implement this feature, and so far, I have come up with the following solution.

Is there a way for me to utilize the answer value as the question index after the user clicks "next"?

JS file:

"use strict";

let quiz = {
  title: "Asbestos Quiz",
  questions: [
    {
      text: 'Do you need help with an Asbestos Survey?',
      answers: [
        {
          text: "Yes",
          value: '2'`enter code here`
        },
        {
          text: "No",
          value: '3'
        },       
      ]
    },
    {
      text: 'Was your property constructed pre 2000',
      answers: [
        {
          text: "Yes",
          value: '4'
        },
        {
          text: "No",
          value: '5'
        },
      ]
    },
    {
      text: 'Do you need an Asbestos Management plan?',
      answers: [
        {
          text: "Yes",
          value: '6'
        },
        {
          text: "No",
          value: '7'
        },
      ]
    }
  ]
};

var app = new Vue({
  el: "#app",
  data: {
    quiz: quiz,
    questionIndex: 0,
    responses: [],
    errors: [],
    error: ''
  },
  
  methods: {
    prev: function() {
      this.questionIndex--;
    },
    
    next: function() {
      if (this.responses[this.questionIndex] === undefined) {
        this.errors[this.questionIndex] = 1;
        this.error = 'Please select your answer';
      } 
      else {
        this.errors[this.questionIndex] = 0;
        this.questionIndex++;
      } 
    },
    score: function() {
      
    },
    
    playAgain: function() {
      this.questionIndex = 0;
    }
  }
});


HTML:

<html lang="en">
  <head>
    <title>Vue quiz/survey</title>
    <meta name="viewport" content="width=device-width"/>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <!-- <link rel="stylesheet" href="index.css"> -->
  </head>
  <body>
          <div id="app">
    <div class="container">
      <div class="jumbotron mt-3">
        <h1 class="mb-5">{{ quiz.title }}</h1>
        <hr>
         <p v-if="errors[questionIndex]" class="alert alert-danger">
            {{ error }}
          </p>
        <div v-for="(question, index) in quiz.questions">
          <div v-show="index === questionIndex">
           
            <h4 class="mt-5 mb-3">{{ question.text }}</h4> 
            
            <div v-for="answer in question.answers" class="form-check">
              <label class="form-check-label">
                <input class="form-check-input" type="radio"
                     :value="answer.value"
                     :name="index"
                     v-model="responses[index]">
                {{answer.text}}
              </label>
            </div>
            
            <div class="mt-5">
              <button 
                 class="btn btn-primary" 
                 v-if="questionIndex > 0" 
                 @click="prev">
                  prev
              </button>
              <button class="btn btn-secondary" @click="next">
                  next
              </button>  
            </div>
          </div>
        </div>
        
        <div v-show="questionIndex === quiz.questions.length">
          <h3>Your Results</h3>
          <p>
            You are: {{ score() }}
          </p>
          
          <button class="btn btn-success" @click="playAgain">
            Play Again!
          </button>
        </div>
      </div>
    </div>
  </div>
        <script type="text/javascript" src="index.js"></script>
    </body>
</html>

Answer №1

After finding this exercise intriguing, I dedicated some time to create an implementation in a Vue CLI sandbox app that I developed for experimenting with different concepts.

I gained valuable insights during the process, and hopefully, you will find it beneficial as well. I have left the 'Previous' functionality as a TODO if you wish to incorporate it on your own.

QuizQuestions.vue

<template>
  <div class="quiz-questions">
    <div class="jumbotron mt-3">
      <h1 class="mb-5">{{ quiz.title }}</h1>
      <hr>

      <question v-if="!showResults" :question="currentQuestion" @answer-selected="processAnswer" />

      <div class="mt-5">
        <button class="btn btn-primary" v-if="currentQuestionId > 1 && !showResults" @click="getPreviousQuestion">
          prev
        </button>
        <button v-if="!showResults" class="btn btn-secondary" @click="getNextQuestion">
          {{ nextButtonLabel }}
        </button>
      </div>

      <div v-if="showResults">
        <h3>Your Results</h3>
        <table class="table table-bordered">
          <thead>
            <tr>
              <th>QUESTION</th>
              <th>ANSWER</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(response, index) in responses" :key="index">
              <td>{{ getQuestionText(response.questionId) }}</td>
              <td>{{ getAnswerText(response.answerId) }}</td>
            </tr>
          </tbody>
        </table>

        <button class="btn btn-success" @click="playAgain">
          Play Again!
        </button>
      </div>
    </div>

  </div>
</template>

<script>
  // Code logic here...
</script>

Question.vue

<template>
  <div class="question">
    <h4 class="mt-5 mb-3">{{ question.text }}</h4>

    <div class="form-check" v-for="(answer, idx) in question.answers" :key="idx">
      <input class="form-check-input" type="radio"
        :value="answer.id" v-model="answerId" @change="answerSelected">
      <label class="form-check-label">
        {{answer.text}}
      </label>
    </div>

  </div>
</template>

<script>
  // Code logic here...
</script>

I made adjustments to your test data by including various ID properties for easier tracking and introduced additional placeholder questions for testing purposes.

quiz.js

// Quiz data here...
export default quiz;

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

Unable to display a mesh using THREE js

Could there be an issue with my implementation of THREE.Mesh? I'm attempting to generate a torus mesh in three.js using what I believe to be correct mathematical calculations. However, the result is only displaying a portion of the torus, and changing ...

Updating the state of an array containing objects within an array of objects in React

I have a state called invoices, which is an array of objects structured like this: const [invoices, setInvoices] = useState([ { id: 123, tag_number: "", item_amounts: [ { item: "processing", amount: 159 }, { i ...

``There seems to be an issue with disapplying a CSS class using JavaScript

I've designed a website that appears to have multiple pages, but in reality, all the content is contained within one HTML file: index.html. Using javascript and CSS, I have divided the site into a "home" position and an "inside" position similar to a ...

Challenges encountered when using setState to assign values

Just started using React and running into an issue with updating state when changes are made to a Textfield. I'm working with a functional component where the initial state is set using useState. I feel like I might be overlooking something simple... ...

What are some ways I can efficiently load large background images on my website, either through lazy loading or pre

Just dipping my toes into the world of javascript. I'm currently tackling the challenge of lazy loading some large background images on my website. My goal is to have a "loading" gif displayed while the image is being loaded, similar to how it works ...

Tips on using the ref attribute in Vue.js to focus on an input element

In my Vue.js component for 2FA, I have implemented the following structure: <template> <div :class="onwhite ? 'on-white' : ''"> <input :id="`n1`" ref="n1" v-model=&quo ...

Sending information to a PHP script using Ajax

I am working on a project that involves input fields sending data to a PHP page for processing, and then displaying the results without reloading the page. However, I have encountered an issue where no data seems to be passed through. Below is my current s ...

Issue with Vue canvas $ref not being defined on resize causing error, but oddly still seems to function correctly

Within my application, there exists a tabbed interface. One of the tabs contains a canvas element that dynamically adjusts its size to fit the window whenever it is resized. The functionality works seamlessly at first, but upon switching tabs and returning ...

Assessing the validity of a boolean condition as either true or false while iterating through a for loop

I am facing an issue that involves converting a boolean value to true or false if a string contains the word "unlimited". Additionally, I am adding a subscription to a set of values and need to use *NgIf to control page rendering based on this boolean. &l ...

Retrieve a list of all file names within a designated directory using Angular

I am working on my Angular app and I need to list all the file names inside the assets folder. To achieve this, I am planning to utilize the npm library called list-files-in-dir https://www.npmjs.com/package/list-files-in-dir Here is the service impleme ...

What is the best way to deactivate a button using AngularJS?

$scope.date = moment(currentDate); $scope.date1 = moment(currentDate).add(-1, 'days'); function checkDate(){ if ($scope.date > $scope.date1) { return true; } else{ return false; } }; checkDate(); ...

Creating an HTML layout or template directly within a JavaScript bookmarklet

Currently, I am using a bookmarklet that generates a user interface for interaction. The method I have been using involves creating elements using $('<element>').addClass().css({..});, but this approach is proving to be difficult to maintai ...

Troubleshooting AngularJS Get Function Failure

New to the world of AngularJS, I find myself faced with a challenge. My .NET MVC WebAPI Restful app is up and running on an IIS server. However, when I attempt to query the API using , the response I receive is: [{"Id":1,"Name":"Glenn Block","Created":"00 ...

Is it possible to update Vuex data without making an API request?

Running a PHP backend and already having the necessary data that I would like to set within my Vuex store presents an interesting challenge. Typically, if the data is readily available and only needs to be passed along to a component, I would encode it usi ...

Creating an import map using jspm2 can be done by following these steps

Currently, my goal is to utilize JSPM module loader to import javascript packages from npm instead of CDN and employ an offline package loader. Now, the next step involves incorporating an importmap script in order to successfully import modules like rea ...

JavaScript - combining elements of an array of time

I've encountered a challenge where I need to calculate the total time duration from an array that contains time durations like ['00:30', '01:30', '03:00', '04:30']. The code snippet I'm using for this task ...

Trigger an alert box using JavaScript after a successful submission

PHP Script Explanation The following PHP script is executed once the corresponding form has been filled out: <?php $connect = mysql_connect($h, $u, $p) or die ("Connection Failed."); mysql_select_db($db); ## Prevent SQL Inje ...

Tips for resizing mesh along the global axis

Have you ever used an online 3D editor that allows you to manipulate individual meshes by moving, scaling, and rotating them? This editor utilizes custom transform controls inspired by the TransformControls code from three.js. Here is a snippet of code fro ...

Bundling JSPM with an external system JS file

Currently, I am loading my Angular2 file as a System js module from a CDN. Within my project, I have multiple files importing various System js modules of Angular2. However, I am now looking to bundle my local JavaScript files using JSPM. But when I ente ...

Logging on the client side with node.js without the need for additional modules

Do you think it's a good idea to wrap my minified JavaScript code in a try-catch block so that if a client-side error occurs, it sends a POST request to my server and appends the error to a log file on the server? The main concern here is security - ...