Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

143
Views
Star Rating Js + html with symfony

I'm working on a project with symfony 4. I want to implement a star rating system. I display 5 stars in each row in a table. I have two problems, one is more important than the other.

So the first issue is that I want to be able to retrieve the value of the star I selected. If I select 5 stars, I want to get that value back in my entity controller.

The second issue is that, currently, let's say I have 5 items in my table, so 5 rows. Currently, if I select 5 stars in one row it's selected for all rows and I can't select another value anymore. So, it's global or something.

Here is the javascript I'm using:

<script>
    const stars = document.querySelectorAll('.star');
    let check = false;
    stars.forEach(star => {
        star.addEventListener('mouseover', selectStars);
        star.addEventListener('mouseleave', unselectStars);
        star.addEventListener('click', activeSelect);
    })

    function selectStars(e) {
        const data = e.target;
        const etoiles = priviousSiblings(data);
        if (!check) {
            etoiles.forEach(etoile => {
                etoile.classList.add('hover');
            })
        }

    }

    function unselectStars(e) {
        const data = e.target;
        const etoiles = priviousSiblings(data);
        if (!check) {
            etoiles.forEach(etoile => {
                etoile.classList.remove('hover');
            })
        }
    }

    function activeSelect(e) {
        if (!check) {
            check = true;
            document.querySelector('.note').innerHTML = 'Note ' + e.target.dataset.note;
        }
    }

    function priviousSiblings(data) {
        let values = [data];
        while (data === data.previousSibling) {
            if (data.nodeName === 'I') {
                values.push(data);
            }
        }
        return values;
    }
</script>

And Here is the twig.html I'm displaying:

<td>
    <i class="star" data-note="1">&#9733;</i>
    <i class="star" data-note="2">&#9733;</i>
    <i class="star" data-note="3">&#9733;</i>
    <i class="star" data-note="4">&#9733;</i>
    <i class="star" data-note="5">&#9733;</i>
    <i class="note">Note:</i>
</td>

I want to be able to retrieve the value once I made a selection, and to have a different selection for each row I have.

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

The problem is with the "mouseover" and "mouseleave" event handlers - selectStars and unselectStars. In "selectStars", you are adding the class to only one star. And in "unselectStars", you were not resetting, or applying the "remove" class method to other stars.

Anyway, here is how I have achieved what you are trying to do:

const ratings = document.querySelectorAll('.rating');
ratings.forEach(rating =>
  rating.addEventListener('mouseleave', ratingHandler)
);

const stars = document.querySelectorAll('.rating .star');
stars.forEach(star => {
  star.addEventListener('mouseover', starSelection);
  star.addEventListener('mouseleave', starSelection);
  star.addEventListener('click', activeSelect);
});

function ratingHandler(e) {
  const childStars = e.target.children;
  for(let i = 0; i < childStars.length; i++) {
    const star = childStars.item(i)
    if (star.dataset.checked === "true") {
      star.classList.add('hover');
    }
    else {
      star.classList.remove('hover');
    }
  }
}

function starSelection(e) {
  const parent = e.target.parentElement
  const childStars = parent.children;
  const dataset = e.target.dataset;
  const note = +dataset.note; // Convert note (string) to note (number)
  for (let i = 0; i < childStars.length; i++) {
    const star = childStars.item(i)
    if (+star.dataset.note > note) {
      star.classList.remove('hover');
    } else {
      star.classList.add('hover');
    }
  }
}

function activeSelect(e) {
  const parent = e.target.parentElement
  const childStars = parent.children;
  const dataset = e.target.dataset;
  const note = +dataset.note; // Convert note (string) to note (number)
  for (let i = 0; i < childStars.length; i++) {
    const star = childStars.item(i)
    if (+star.dataset.note > note) {
      star.classList.remove('hover');
      star.dataset.checked = "false";
    } else {
      star.classList.add('hover');
      star.dataset.checked = "true";
    }
  }

  const noteTextElement = parent.parentElement.lastElementChild.children.item(0)
  noteTextElement.innerText = `Note: ${note}`;
}

You might notice I have a .rating class component. This is a div which I have created to hold all these "stars". Here is a link to a codepen I have created. Feel free to play around with it.

And as a note, please provide codepen (or any other) demos so that we can debug a bit better and faster.

I hope the codepen link would help you solve your problem.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!