Search code examples
javascripthtmljquerycssrating

Reset rating when clicking outside of the DIV


I am doing a rating exercise in which I have to be able to reset my selection if I click anywhere outside of the DIV that contains the symbols, but for any reason I am unable to find the right solution.

By now, every time I execute the code, I get the message "Uncaught TypeError: Cannot read property 'classList' of null" in the line 17 of my javascript code. Does anyone know what am I doing wrong? I am out of imagination already. I copy my code below:

HTML

<!doctype html>
<html class="no-js" lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title>cosanueva</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=1024, initial-scale=1">

    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css">
    <link rel="stylesheet" href="estilos.css">
    <script src="https://use.fontawesome.com/releases/v5.0.8/js/all.js"></script>

    <script src="javascript.js"></script>

  </head>
  
  <body>
    <div class="container box">
    <div class="col-12 rating">
      <input type="radio" id="smile5" name="rating" value="5" /><label class="full" for="smile5"></label>
      <input type="radio" id="smile4" name="rating" value="4" /><label class="full" for="smile4"></label>
      <input type="radio" id="smile3" name="rating" value="3" /><label class="full" for="smile3"></label>
      <input type="radio" id="smile2" name="rating" value="2" /><label class="full" for="smile2"></label>
      <input type="radio" id="smile1" name="rating" value="1" /><label class="full" for="smile1"></label>
  </div>
  </div>

  </body>
</html>

CSS

/****** Style Smile Rating Widget *****/

.rating {
  border: none;
  float: left;
  text-align: center;
}

.rating>input {
  display: none;
}

.rating>label:before {
  margin: 5px;
  font-size: 1.25em;
  font-family: FontAwesome;
  display: inline-block;
  content: "\f118";
}

.rating>label {
  color: #ddd;
  float: right;
}


/***** CSS Magic to Highlight Smile on Hover *****/

.rating>input:checked~label,

/* show gold smile when clicked */

.rating:not(:checked)>label:hover,

/* hover current smile */

.rating:not(:checked)>label:hover~label {
  color: #FFD700;
}


/* hover previous smile in list */

.rating>input:checked+label:hover,

/* hover current smile when changing rating */

.rating>input:checked~label:hover,
.rating>label:hover~input:checked~label,

/* lighten current selection */

.rating>input:checked~label:hover~label {
  color: #FFED85;
}

JAVASCRIPT

    var box = document.querySelector(".box");

// Detect all clicks on the document
document.addEventListener("click", function(event) {
    // If user clicks inside the element, do nothing
    if (event.target.closest(".box")) return; 
    // If user clicks outside the element,
    box.classList.add(".rating>label");
});

Thank you in advance and hope you can help me! :)


Solution

  • Check this one :

    var radios = document.querySelectorAll('input[name=rating]');
    
    document.addEventListener("click", function(event) {
      var targ = event.target.parentElement;
      if (!(targ && targ.classList.contains('rating'))) {
        radios.forEach(e => {
          if (e.checked) {
            e.checked = false;
          }
        });
      }
    });
    .rating {
      border: none;
      float: left;
      text-align: center;
    }
    
    .rating>input {
      display: none;
    }
    
    .rating>label:before {
      margin: 5px;
      font-size: 1.25em;
      font-family: FontAwesome;
      display: inline-block;
      content: "\f118";
    }
    
    .rating>label {
      color: #ddd;
      float: right;
    }
    
    .rating>input:checked~label,
    .rating:not(:checked)>label:hover,
    .rating:not(:checked)>label:hover~label {
      color: #FFD700;
    }
    
    .rating>input:checked+label:hover,
    .rating>input:checked~label:hover,
    .rating>label:hover~input:checked~label,
    .rating>input:checked~label:hover~label {
      color: #FFED85;
    }
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css">
    
    <script src="https://use.fontawesome.com/releases/v5.0.8/js/all.js"></script>
    
    <div class="container box">
      <div class="col-12 rating">
        <input type="radio" id="smile5" name="rating" value="5" /><label class="full" for="smile5"></label>
        <input type="radio" id="smile4" name="rating" value="4" /><label class="full" for="smile4"></label>
        <input type="radio" id="smile3" name="rating" value="3" /><label class="full" for="smile3"></label>
        <input type="radio" id="smile2" name="rating" value="2" /><label class="full" for="smile2"></label>
        <input type="radio" id="smile1" name="rating" value="1" /><label class="full" for="smile1"></label>
      </div>
    </div>