Utilizing CSS and Vue to dynamically style elements based on hover events for rating displays

Looking for a simple solution here. I'm working on coding a 5-star rating system.

I have an array set up with 5 possible ratings:

const ratingsArray = [
  {
    name: 'rating1',
    ratingValue: 20,
    isEnabled: ref(false)
  },
  {
    name: 'rating2',
    ratingValue: 40,
    isEnabled: ref(false)
  },
  {
    name: 'rating3',
    ratingValue: 60,
    isEnabled: ref(false)
  },
  {
    name: 'rating4',
    ratingValue: 80,
    isEnabled: ref(false)
  },
  {
    name: 'rating5',
    ratingValue: 100,
    isEnabled: ref(false)
  },
]

This template loops through the array and displays a circle for each entry:

The class 'ratingBoxChecked' is applied to fill the dot with color.

<template>
  <span>
    <div 
      v-for="(rating, index) in ratingsArray" 
      :key="rating.name" 
      @click="updateRating(index, rating.ratingValue)" 
      :class="[rating.isEnabled.value ? 'ratingBoxChecked' : 'ratingBox']">
    </div>
  </span>
</template>

Is there a way to hover over one dot and have the previous ones hovered as well all with the class 'ratingBoxChecked'?

For instance, if I hover over the 3rd dot, I want the first 2 dots to also be enabled! Just like a typical star rating hover effect.

Appreciate any help you can provide!

Answer №1

Disregarding the "click" scenario in this instance (though it can easily be incorporated) - take a look at my StackBlitz to see it in action.

Program Code

<script setup>
import { ref } from 'vue';

const ratings = [
  {
    name: 'rating1',
    value: 20,
  },
  {
    name: 'rating2',
    value: 40,
  },
  {
    name: 'rating3',
    value: 60,
  },
];

// When hovering, this ref will be changed to the index of the rating you hover over
const hoveredRating = ref(-1);
// Function to check if styles/text/... should be changed
const shouldRatingShow = (index) => hoveredRating.value >= index;

// Note: This is a naive implementation. You can also check it based on names (e.g. find the index of a rating based on the name and take all before) and so on and so on
</script>

<template>
  <span>
    <!-- div containing the mouseenter and mouseleave event to change the ref. PS: If you want to make it clickable, this should be a button!! -->
    <div
      v-for="(rating, index) in ratings"
      :key="rating.name"
      @mouseenter="hoveredRating = index"
      @mouseleave="hoveredRating = -1"
    >
      {{ rating.name }}
      {{ shouldRatingShow(index) ? 'on' : 'off' }}
    </div>
  </span>

  <!-- Debug output -->
  {{ hoveredRating }}
</template>

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

Vertically align all items within the div using Bootstrap to achieve perfect centering

I've been working on centering everything within this div vertically, and I've encountered some challenges along the way. Initially, I ensured that my background view extends my container nicely across the screen. Now, I'm looking to create ...

Locate button elements with the class "button" that do not have any images inside them

Below is the code I am currently using for buttons (I prefer not to change it): <a href="#" class="button"> Button text <img src="someimage.png" /> </a> This CSS styled code creates a sleek button with an icon. To round the left sid ...

As I iterate through my array using v-for, I aim to assign each item to a distinct grid location. Can you provide guidance on achieving this?

So, I have this particular component and I am aiming to showcase my data in a grid layout similar to the image provided below: https://i.sstatic.net/ZHSdi.png Currently, I am iterating through the last 3 items in my array with this code: async created(){ ...

Having difficulty adding a border to the SlidesJS frame

I am utilizing the SlidesJS jQuery plugin which can be found here. My goal is to add a border around the slider. I adjusted the CSS section like so: #slides .slidesjs-container { margin-bottom:10px; border-color: #ff5566; border-width: 3px; borde ...

What is the method for dynamically invoking computed props in templates?

Here is a similar situation: <script> export default { computed: { example () { return 'bar' } } } </script> <template> <div> <!-- Unfortunately, attempting to call "this" ...

What is the reason for the disparity between CSS box-sizing content-box and border-box?

Consider the following example where I only changed the CSS box-sizing property from content-box to border-box. The resulting output difference is significant. Give this code a try: .box1 { width: 300px; height: 100px; border: 1px solid blue; pa ...

Tips for adjusting text placement within table cells without altering the original dimensions of the td element?

In my simple HTML table, I am trying to align the text in all columns to the right side in the second row. After exploring this question and this one, which suggest setting box-sizing: border-box;, I found that the desired result was not achieved. The widt ...

What is preventing me from invoking the function that I built using the Function() constructor?

Utilizing the Function Constructor within a function to generate functions during its call. Below is the constructor: funcGenerator(f) { return new Function( "value", "try{ return " + f + '; } catch (e) { ret ...

Row-eq-height does not function properly with the layout of my webpage when trying to bootstrap equal column heights

I am currently building a webpage and struggling with keeping the left orange div at the same height as the right div. The navigation is represented by the orange div, which contains links. Upon clicking a link, a preview of a .pdf file appears in the righ ...

The absence of underlines for <a href> and <u> is causing an issue

Below is a snippet of code that I am working with: echo "<form> <div id=\"error\"align=\"center\">"; echo "You've either entered the incorrect <b>username</b> or incorrect <b>passwor ...

Apply Class According to Style Property

My current CMS does not seem to apply a class name when an element is floated left or right. Instead of delving into the TinyMCE code, I would prefer to use jQuery to solve this issue. Currently, when aligning an image to the left or right, inline styles ...

Updating charts from the parent component in Vue 3 using Vue-ChartJS version 5.2: A comprehensive guide

Vue is new to me, and I must confess that I am struggling to understand how to update a graph from its parent component. I can see that the data is being updated in the vue-dev-tools, but for some reason, the graph is not updating accordingly. Unfortunatel ...

Tips for avoiding Navbar dropdowns covering other content

Using bootstrap 4 for a project and experiencing an issue with the navbar overlapping the content. How do I make the remaining content adjust when toggling the dropdown menu? To address this problem, I have applied a 50px margin to the body element. The ...

Setting multiple positions for jQueryUI tooltips based on specific classes

I recently followed these instructions on utilizing jQueryUI tooltip to load content via ajax. (fiddle)(Full Screen). However, I encountered an issue where I'm unable to set a different position for the second tooltip (`.loadtip`) compared to the firs ...

Unable to scroll horizontally beyond 200 viewport widths

I'm facing an issue with my code that switches between vertical and horizontal scrolling but seems to have a width limit of 200vw. When I set the min-width to 50vw, only 4 sections are visible, whereas setting it to 100vw (as shown in the example) dis ...

What is the best way to retrieve the unique identifier of dynamically created divs and showcase a message based on that identifier?

Is it possible to retrieve the id of a dynamically generated div and show a unique message when each div is clicked in the code snippet found at this link? function get_random_color() { var letters = '0123456789ABCDEF'.split(''); ...

Tips for executing a function whenever unfamiliar anchor elements are selected in Vue.js 3

I am utilizing a div with v-html to showcase data fetched from a database: <div id="Content" v-html="${Content}"></div> Inside the presented ${Content}, there may be various a tags linking to external pages. I aim to parse ...

Developing visually appealing HTML tables with CSS styles

I'm currently working on a website project and I'm looking to incorporate a table similar to the one shown in the image. While I am familiar with HTML tables, I'm struggling to recreate this specific layout. Despite my best efforts, I haven& ...

Arranging content within columns according to their column position

As I design a grid with three columns, each grid box contains a div with a maximum width of 280px. Sometimes the grid columns exceed this width. To achieve my desired layout, I aim to align the content in the grid boxes so that the left column aligns to th ...

Generate two separate CSS files (Mobile and Desktop versions) by compiling a Stylus (.styl) file using Node.js

Can a single Stylus file be compiled into two separate CSS files? For example, one optimized for mobile without the -moz and webkit elements, and another for cross-browser applications? Thank you. ...