jbernardo
jbernardo

Reputation: 191

Simple rating system

I'm trying to make a rating system, but I have some problems.

here's my html:

<div id="div-stars1">                   
    <img src="assets/imagens/star_empty_na.png" style="width: 25px" id="img-starsna">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star1">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star2">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star3">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star4">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star5">                              
</div>

<div id="div-stars2">                   
    <img src="assets/imagens/star_empty_na.png" style="width: 25px" id="img-starsna">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star6">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star7">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star8">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star9">
    <img src="assets/imagens/star_empty.png" style="width: 25px" class="img-stars" id="img-star10">                             
</div>  

Well, I'll need to have several block codes like this, but I wouldn't like to have many functions to this (# div-stars3, # div-stars4 ... #divstars20). Yes, there are many questions from my poll, but I do not want to repeat code, I mean, I do not want to code any of the same things ($ ("# div-stars1").mouseover (function () {....}), $ ("# div-stars2").mouseover (function () {....}), $ ("# div-stars3")..... So, I'd like some advice from which way to go. I care for a clean, lean and dynamic code.

I did the rating system just with one block code div, no more than one. Now I need to do with many block codes, many questions with many stars, each one answering for your <div>

Thanks.

Upvotes: 0

Views: 235

Answers (3)

Aniket Jha
Aniket Jha

Reputation: 1781

Try this Code for getting a star based rating system.

<!DOCTYPE html>
<html>

<head>
  <!-- Font Awesome Icon Library -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  <style>
    #priorityFlag {
      color: rgb(241, 241, 70);
      font-size: 1em;
      padding: 0.25em;
      border-width: 1px;
      border-style: solid;
      border-radius: 50%;
    }
    
    .fa-star {}
    
    .fa-star:hover {
      cursor: pointer;
    }
    
    .checkedStar {
      color: rgb(248, 248, 41);
    }
    
    #ratingBox {
      width: 150px;
    }
    
    #ratinngBox::after {
      content: '';
      display: block;
      clear: both;
    }
    
    #starsBox {
      
      float: left;
      width: 70%;
    }
    
    #flagBox {
      width: 30%;
      float: right;
    }
  </style>
</head>

<body>

  <h2>Star Rating</h2>
  <div id="ratingBox">
    <div id="starsBox">
      <span class="fa fa-star checkedStar" data-priority-value="0" data-status-marked="true"></span>
      <span class="fa fa-star" data-priority-value="1" data-status-marked="false"></span>
      <span class="fa fa-star" data-priority-value="2" data-status-marked="false"></span>
      <span class="fa fa-star" data-priority-value="3" data-status-marked="false"></span>
      <span class="fa fa-star" data-priority-value="4" data-status-marked="false"></span>
    </div>
    <div id="flagBox">
      <span class="fa fa-flag" id="priorityFlag"></span>
    </div>
  </div>

  <script>
    var stars = document.getElementsByClassName("fa-star");
    // console.log("obj of strs array",stars);
    Array.prototype.forEach.call(stars, (star) => star.addEventListener("click", setPriority));

    var rateColors = ['rgb(248, 248, 41)', 'gold', 'orange', 'darkorange', 'red'];
    var flag = document.getElementById("priorityFlag");


    function setPriority(event) {
      var star = event.srcElement;
      var priority = star.getAttribute("data-priority-value");
      //  console.log("proirity is ",priority);
      var index = priority;

      var markedStar = star.getAttribute("data-status-marked");
      // console.log("is this star marked status",markedStar,"index is ",index);
      if (markedStar == "false")
        markStar(index);
      else //if(markedStar=="true")
        unMarkStar(index);
      // else
      // console.log("extremly wrong happening in setPriority function");
    }

    function markStar(index) {

      for (let i = 0; i <= index; i++) {
        stars[i].style.color = rateColors[index];
        // console.log("inside markStar marking "+i+" th star marked");
        stars[i].setAttribute("data-status-marked", "true");

        // console.log("true marked obj",stars[i],"marked status is",stars[i].getAttribute("data-status-marked"));
      }
      updateFlag(index);
    }

    function unMarkStar(index) {
      for (let i = 1; i < stars.length; i++) {
        // console.log("marking",`${i}`,stars[i]);
        stars[i].style.color = 'black';
        stars[i].setAttribute("data-status-marked", "false");
      }
      // console.log("inside umMarkStar",index,` nextline is markStar(${index})false`);
      markStar(index);

    }

    function updateFlag(index) {

      // console.log("update flag acc to",index,rateColors[index]);//updating flag color to this index of flagColors array
      flag.style.color = rateColors[index];
      flag.style.borderColor = rateColors[index];


    }
  </script>
</body>

</html>

Upvotes: 0

atcastroviejo
atcastroviejo

Reputation: 263

You could add a class to all divs and use the Class Selector:

$( ".class" ).on( "mouseover", function() {
  ...
});

If you don't want to use classes, you might want to do what @John Wu suggested. It works the same.

Then, to know which div triggered the function, you can use event.target:

$( ".class" ).on( "mouseover", function() {
  // alert the id of the hovered div
  alert( event.target.id );
});

Hope this answers your question.

Upvotes: 1

John Wu
John Wu

Reputation: 52280

If you want to apply a handler to multiple DIVs that have the same name except for the number at the end, you could the "starts with" selector:

$("DIV[ID^='divstars']").mouseover(etc.)

Upvotes: 0

Related Questions