A guide on customizing the appearance of individual items in a vue v-for loop based on specific conditions

I am currently developing a multiple choice quiz game and I want the selected answer by the user to change color, either red or green, depending on its correctness. To achieve this, I have created a variable called selected that correctly updates when the user clicks an option. Additionally, all items within the v-for loop are changing colors based on the correctness of the answers. However, my main issue lies in isolating just one item within the v-for loop to change color.

Below is the relevant HTML code snippet:

<button type="button" class="btn answer" v-for="option in options" @click="checkAnswer(option)" @click="selected = option" :style="{backgroundColor: colour}">
    {{option}}<br/>
  </button>
  <button type="button" @click="getQ" @click="shuffle(options)" class="btn button next">Next</button>
  

Here is the corresponding JavaScript section:

let colour = Vue.ref('');
let selected = Vue.ref('');
let options = Vue.ref([correctAnswer, incorrectAnswerOne, incorrectAnswerTwo, incorrectAnswerThree]);

// Methods

let shuffle = function(options) {
 let num = options.length, t, raInt;
 //while there are remaining elements to shuffle
    while (num) {
      //choose random
      raInt = Math.floor(Math.random() * num--);
      //swap with current element
      t = options[num];
      options[num] = options[raInt];
      options[raInt] = t;
    }
    return options;
};

let checkAnswer = function(clicked) {
 console.log(clicked.value);
 console.log(correctAnswer.value);
 if (clicked.value == correctAnswer.value) { 
   this.result = "Correct!"; 
   this.colour = "green";
} else {
   this.result = "Incorrect!"; 
   this.colour = "red";
};
};

And here is some CSS styling:

.answer {
   width: 100%;
   background-color: #dbdbdb;
   padding: 4% 2%;
   margin: 1 0;
}

.answer:hover {
   background-color: #c2c2c2
}

I haven't experimented much with different solutions yet. I'm unsure about how to tackle the task at hand. In a previous project, I successfully styled one div based on the selection of another div, but modifying only a specific part of a v-for loop remains uncharted territory for me. Any assistance would be greatly appreciated. Thank you!

Answer №1

To display different color styles based on conditions, follow the code snippet below:

const { ref, computed } = Vue
const app = Vue.createApp({
  setup() {
    let correctAnswer = 3
    let incorrectAnswerOne = 1
    let incorrectAnswerTwo = 2
    let incorrectAnswerThree = 4
    let colour = ref('');
    let selected = ref('');
    let options = ref([correctAnswer, incorrectAnswerOne, incorrectAnswerTwo, incorrectAnswerThree]);
    let shuffled = ref([])
    
    let shuffle = (array) => {
      selected.value = null
      let currentIndex = array.length,  randomIndex;
      while (currentIndex != 0) {
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex--;
        [array[currentIndex], array[randomIndex]] = [
          array[randomIndex], array[currentIndex]];
      }
      shuffled.value = array;
    };
    shuffle(options.value)

    let checkAnswer = function(clicked) {
      // 👇 set selected  
      selected.value = clicked
      if (clicked == correctAnswer) { 
        this.result = "Correct!";
        this.colour = "green";
      } else {
        this.result = "Incorrect!"; 
        this.colour = "red";
      };
    };
  
    return { colour, selected, options, shuffle, checkAnswer, shuffled }
  },
})
app.mount('#demo')
.answer {
   width: 100%;
   background-color: #dbdbdb;
   padding: .5em 2em;
   margin: 1 0;
 }

 .answer:hover {
   background-color: #c2c2c2
 }
 
 .btns {
  display: flex;
 }
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <div class="btns">
  <div v-for="(option, i) in shuffled" :key="i" >
                                                               <!-- 👇 condition -->
    <button class="answer" @click="checkAnswer(option)" :style="selected == option && {backgroundColor: colour}">
      {{option}}<br/>
    </button>
  </div>
  <button type="button" @click="getQ, shuffle(options)" class="btn button next">Next</button>
</div>

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

Encountered Node.js & MySQL error: 1251 - Client not able to support authentication protocol requested by server. It is recommended to upgrade MySQL client for resolving this

I currently only have the following code snippet: const Sequelize = require('sequelize'); const sequelize = new Sequelize('database', 'root', 'passwd', { host: 'localhost', dialect: 'mysql', ...

Displaying an RSS feed inside a designated div element

Seeking assistance from all you wonderful individuals for what seems to be a simple problem. Here is the HTML code I am working with: <div id="rssfeed"></div> Along with JavaScript that includes the FeedEK plugin $(document).ready(function ...

Applying binary information to an image

Let's say I have an <img/>. The img is initially set with src='http://somelocation/getmypic'. Later on, there might be a need to change the content of the image based on some ajax call that returns binary data. However, this decision c ...

The issue arises when the cache code in jQuery Ajax interferes with the callback function, causing it to

I encountered an issue with my code related to cache. The problem arises when there is an ajax call with a callback in the success function. var localCache = { /** * timeout for cache in millis * @type {number} */ timeout: 30000, ...

Combining ApolloProvider and StatsigProvider in ReactJs: A Step-by-Step Guide

Currently in my React (Next.js) application, I am utilizing statsig-react to switch between mastergraphql endpoint URLs. However, I am encountering an issue when trying to connect statsig with Apollo. This is how my app.js file looks like: const apollo = ...

Container for Magazines using HTML and CSS

Looking to develop a digital magazine application with smooth swipe transitions and fade in effects when swiping left and right. I attempted using jQuery.mobile, but struggled with adapting the background image height. My goal is to create a universal web ...

Attempting to transform a numerical value into CSS syntax

Currently, I am attempting to loop through several DIV elements, extract a numerical value from each DIV, and then based on that value matching a specific value in the JavaScript code, assign a particular CSS Class back to the original DIV. This is the sn ...

Error retrieving data from the ngresource properties resource

In the code snippet below, I have a simple factory that requests a json object containing location information. The requests are successful and the data is present in the object. However, there seems to be a scope problem as I am unable to access the prope ...

Tips for ensuring long text wraps to the next line when it exceeds the width of the browser window

I'm struggling with CSS styles and properties. I want the text to wrap to the next line instead of overflowing off the browser screen. I've illustrated what's currently happening versus what I actually need. https://i.stack.imgur.com/mPGt8 ...

The leave animation for Angular's ngAnimate and ng-view feature appears to be malfunctioning

angular version: 1.6.1 I am attempting to create a fade in/out effect for my ng-view element, however, I am encountering an issue where only the enter animation is functioning properly. This is the relevant HTML code: <main class="main" ng-view>&l ...

What is the best way to execute the command "npm run watch" on a server for a Laravel project?

Seeking assistance with an issue I've encountered – I can't find the solution on my own. I am currently attempting to immediately update changes made in the code using "np m run watch", but I'm unsure how to do so on the server. All the f ...

Encountering an E2BIG error when running vue-cli-service build

Currently, I am working on a Vue.js 2 application development project using Ubuntu 20.04.1 LTS as my operating system. Here is how my package.json file is structured: { "name": "my-app", "version": "0.0.1", &qu ...

Transition between different segments

Currently working on a sapui5 fiori app, I find myself utilizing multiple fragments based on the mode (read, create, edit). However, I am stuck on how to smoothly navigate from one fragment to another, and more importantly, how to seamlessly return to th ...

Leveraging module in vue.config.js

I'm encountering an issue while trying to implement the code below in my vue.config.js file. The error message indicates that the module is not allowed. I understand that there are configureWebpack and chainWebpack options available, but I'm unsu ...

The alignment of labels and text inputs using CSS flexbox is not correct

I am attempting to create a responsive layout for the labels and text inputs in my HTML code. I want them to align in a single row, with one label and one text input per row when the screen width is below a certain threshold. Once the screen width exceeds ...

What can you do with jQuery and an array or JSON data

Imagine having the following array: [{k:2, v:"Stack"}, {k:5, v:"Over"}, , {k:9, v:"flow"}] Is there a way to select elements based on certain criteria without using a traditional for/foreach loop? For example, can I select all keys with values less than ...

Interactive section for user input

I am looking to add a commenting feature to my website that allows for dynamic editing. Essentially, I want users to be able to click on an "Edit" span next to a comment and have it transform into an editable textarea. Once the user makes their changes and ...

Fetching server-side data for isomorphic React app: A guide to accessing cookies

Currently, I am in the process of developing an isomorphic/universal React + Redux + Express application. The method I use for server-side data fetching is quite standard: I identify the routes that match the URL, call the appropriate data-fetching functio ...

I'm looking to have a span and an input side by side, both spanning the full width of the containing div. How can I achieve this?

In my code snippet below: <html> <body> <div style="width: 700px;"> <span>test</span> <input style="width: 100%;"></input> </div> </body> </html> I am facing an issue where the span and input el ...

Having trouble with the API authentication call, receiving a "Failed to load resource: net::ERR_CONNECTION_REFUSED" error message

I am facing an issue with my Vue and .net application. Whenever I run "NPM start serve," it successfully builds the app. The app is running locally at: http://localhost:8080/ However, when I attempt to log in, I encounter the following error: Console err ...