0

I implemented a user star rating system using html and css only. The rating works perfectly, but when I try to duplicate it I'm having issues with the rating saving on the duplicate entry. Please see codepen (https://codepen.io/margin707/pen/mdebMOZ) or code below:

/*rating1*/

.ratingControl {
  position: relative;
  width: 220px;
  height: 45px;
  user-select: none;
  margin: 0 auto;
}

.ratinginput1 {
  visibility: hidden;
}

.ratingControl-stars {
  position: absolute;
  top: 0;
  width: 40px;
  height: 65px;
  background-image: url('https://i.imgur.com/86OG0nb.png');
  background-size: auto 45px;
  background-repeat: no-repeat;
  cursor: pointer;
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

.ratingControl-stars:hover,
.ratingControl-stars:hover~.ratingControl-stars,
.ratinginput1:checked~.ratingControl-stars {
  background-image: url('https://i.imgur.com/yGnRfYd.png') !important;
}

.ratingControl-stars:active,
.ratingControl-stars:active~.ratingControl-stars,
.ratinginput1:checked~.ratingControl-stars:active {
  background-image: url('https://i.imgur.com/yGnRfYd.png') !important;
}

.ratingControl-stars--1 {
  left: 10px;
}

.ratingControl-stars--2 {
  left: 50px;
}

.ratingControl-stars--3 {
  left: 90px;
}

.ratingControl-stars--4 {
  left: 130px;
}

.ratingControl-stars--5 {
  left: 170px;
}


/*rating2*/

.ratingControl2 {
  position: relative;
  width: 220px;
  height: 45px;
  user-select: none;
  margin: 0 auto;
}

.ratinginput2 {
  visibility: hidden;
}

.ratingControl2-stars {
  position: absolute;
  top: 0;
  width: 40px;
  height: 65px;
  background-image: url('https://i.imgur.com/86OG0nb.png');
  background-size: auto 45px;
  background-repeat: no-repeat;
  cursor: pointer;
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

.ratingControl2-stars:hover,
.ratingControl2-stars:hover~.ratingControl2-stars,
.ratinginput2:checked~.ratingControl2-stars {
  background-image: url('https://i.imgur.com/yGnRfYd.png') !important;
}

.ratingControl2-stars:active,
.ratingControl2-stars:active~.ratingControl2-stars,
.ratinginput2:checked~.ratingControl2-stars:active {
  background-image: url('https://i.imgur.com/yGnRfYd.png') !important;
}

.ratingControl2-stars--1 {
  left: 10px;
}

.ratingControl2-stars--2 {
  left: 50px;
}

.ratingControl2-stars--3 {
  left: 90px;
}

.ratingControl2-stars--4 {
  left: 130px;
}

.ratingControl2-stars--5 {
  left: 170px;
}
<div class="ratingControl"><input class="ratinginput1" id="rating-5" name="rating" type="radio" value="5" />
  <label class="filledStars ratingControl-stars ratingControl-stars--5" for="rating-5">5</label>
  <input class="ratinginput1" id="rating-4" name="rating" type="radio" value="4" />
  <label class="filledStars ratingControl-stars ratingControl-stars--4" for="rating-4">4</label>
  <input class="ratinginput1" id="rating-3" name="rating" type="radio" value="3" />
  <label class="filledStars ratingControl-stars ratingControl-stars--3" for="rating-3">3</label>
  <input class="ratinginput1" id="rating-2" name="rating" type="radio" value="2" />
  <label class="filledStars ratingControl-stars ratingControl-stars--2" for="rating-2">2</label>
  <input class="ratinginput1" id="rating-1" name="rating" type="radio" value="1" />
  <label class="filledStars ratingControl-stars ratingControl-stars--1" for="rating-1">1</label></div>
<br>
<div class="ratingControl2"><input class="ratinginput2" id="rating-5" name="rating" type="radio" value="5" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--5" for="rating-5">5</label>
  <input class="ratinginput2" id="rating-4" name="rating" type="radio" value="4" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--4" for="rating-4">4</label>
  <input class="ratinginput2" id="rating-3" name="rating" type="radio" value="3" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--3" for="rating-3">3</label>
  <input class="ratinginput2" id="rating-2" name="rating" type="radio" value="2" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--2" for="rating-2">2</label>
  <input class="ratinginput2" id="rating-1" name="rating" type="radio" value="1" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--1" for="rating-1">1</label></div>

I tried changing all the class names for the duplicate entry but still it will only update the original one. I suspect it has something to do with the ~ symbol but couldn't get to the root of the problem after hours of debugging. Any help is much appreciated!

connexo
  • 53,704
  • 14
  • 91
  • 128
  • You cannot have more than one of any given `id` value in a document. You need to make sure to never have duplicate `id`s in your code; this is **mandatory**. Also, all your radio buttons have the same `name` attribute, meaning that only one of all of them can be selected. Make sure that all radio buttons *in one group* share the name. – connexo Apr 08 '20 at 06:39
  • `id` should be a unique attribute. You're using it twice for each star "button" – GalAbra Apr 08 '20 at 06:39
  • Thanks for the quick responses. I changed the input id, input name, and input value on the second rating to be different, yet I'm still having the same issue :/ (https://codepen.io/margin707/pen/mdebMOZ) – Mark Argin Apr 08 '20 at 06:42
  • you need to change the "for" values of the second group. – Fabrizio Calderan Apr 08 '20 at 06:49

2 Answers2

0

You cannot have more than one of any given id value in a document. You need to make sure to never have duplicate ids in your code; this is mandatory.

Also, all your radio buttons have the same name attribute, meaning that only one of all of them can be selected. Make sure that all radio buttons in one group share the name, and that each group gets a different name. You can usually achieve that easily by adding a number at the end of the name attribute, and count that number up:

/*rating1*/

.ratingControl {
  position: relative;
  width: 220px;
  height: 45px;
  user-select: none;
  margin: 0 auto;
}

.ratinginput1 {
  visibility: hidden;
}

.ratingControl-stars {
  position: absolute;
  top: 0;
  width: 40px;
  height: 65px;
  background-image: url('https://i.imgur.com/86OG0nb.png');
  background-size: auto 45px;
  background-repeat: no-repeat;
  cursor: pointer;
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

.ratingControl-stars:hover,
.ratingControl-stars:hover~.ratingControl-stars,
.ratinginput1:checked~.ratingControl-stars {
  background-image: url('https://i.imgur.com/yGnRfYd.png') !important;
}

.ratingControl-stars:active,
.ratingControl-stars:active~.ratingControl-stars,
.ratinginput1:checked~.ratingControl-stars:active {
  background-image: url('https://i.imgur.com/yGnRfYd.png') !important;
}

.ratingControl-stars--1 {
  left: 10px;
}

.ratingControl-stars--2 {
  left: 50px;
}

.ratingControl-stars--3 {
  left: 90px;
}

.ratingControl-stars--4 {
  left: 130px;
}

.ratingControl-stars--5 {
  left: 170px;
}


/*rating2*/

.ratingControl2 {
  position: relative;
  width: 220px;
  height: 45px;
  user-select: none;
  margin: 0 auto;
}

.ratinginput2 {
  visibility: hidden;
}

.ratingControl2-stars {
  position: absolute;
  top: 0;
  width: 40px;
  height: 65px;
  background-image: url('https://i.imgur.com/86OG0nb.png');
  background-size: auto 45px;
  background-repeat: no-repeat;
  cursor: pointer;
  text-indent: 100%;
  white-space: nowrap;
  overflow: hidden;
}

.ratingControl2-stars:hover,
.ratingControl2-stars:hover~.ratingControl2-stars,
.ratinginput2:checked~.ratingControl2-stars {
  background-image: url('https://i.imgur.com/yGnRfYd.png') !important;
}

.ratingControl2-stars:active,
.ratingControl2-stars:active~.ratingControl2-stars,
.ratinginput2:checked~.ratingControl2-stars:active {
  background-image: url('https://i.imgur.com/yGnRfYd.png') !important;
}

.ratingControl2-stars--1 {
  left: 10px;
}

.ratingControl2-stars--2 {
  left: 50px;
}

.ratingControl2-stars--3 {
  left: 90px;
}

.ratingControl2-stars--4 {
  left: 130px;
}

.ratingControl2-stars--5 {
  left: 170px;
}
<div class="ratingControl">
  <input class="ratinginput1" id="group-0-rating-5" name="rating-0" type="radio" value="5" />
  <label class="filledStars ratingControl-stars ratingControl-stars--5" for="group-0-rating-5">5</label>
  <input class="ratinginput1" id="group-0-rating-4" name="rating-0" type="radio" value="4" />
  <label class="filledStars ratingControl-stars ratingControl-stars--4" for="group-0-rating-4">4</label>
  <input class="ratinginput1" id="group-0-rating-3" name="rating-0" type="radio" value="3" />
  <label class="filledStars ratingControl-stars ratingControl-stars--3" for="group-0-rating-3">3</label>
  <input class="ratinginput1" id="group-0-rating-2" name="rating-0" type="radio" value="2" />
  <label class="filledStars ratingControl-stars ratingControl-stars--2" for="group-0-rating-2">2</label>
  <input class="ratinginput1" id="group-0-rating-1" name="rating-0" type="radio" value="1" />
  <label class="filledStars ratingControl-stars ratingControl-stars--1" for="group-0-rating-1">1</label>
</div>
<br>
<div class="ratingControl2">
  <input class="ratinginput2" id="group-1-rating-5" name="rating-1" type="radio" value="5" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--5" for="group-1-rating-5">5</label>
  <input class="ratinginput2" id="group-1-rating-4" name="rating-1" type="radio" value="4" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--4" for="group-1-rating-4">4</label>
  <input class="ratinginput2" id="group-1-rating-3" name="rating-1" type="radio" value="3" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--3" for="group-1-rating-3">3</label>
  <input class="ratinginput2" id="group-1-rating-2" name="rating-1" type="radio" value="2" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--2" for="group-1-rating-2">2</label>
  <input class="ratinginput2" id="group-1-rating-1" name="rating-1" type="radio" value="1" />
  <label class="filledStars ratingControl2-stars ratingControl2-stars--1" for="group-1-rating-1">1</label>
</div>
connexo
  • 53,704
  • 14
  • 91
  • 128
  • Just noting that id-values (or classes) which start with numbers, were invalid prior to html-5 https://stackoverflow.com/questions/70579/what-are-valid-values-for-the-id-attribute-in-html – admcfajn Apr 08 '20 at 07:03
  • @admcfajn Thanks for pointing out. Being backwards compatible to old HTML standards does probably no longer have any relevant benefits, but if the cost is so low, why not. Edited accordingly. – connexo Apr 08 '20 at 07:25
0

Thanks for the quick answer. What did it was changing the for attribute for the input.

For the second entry, I changed it from:

<div class="ratingControl2"><input class="ratinginput2" id="rating2-5" name="rating2" type="radio" value="6" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--5" for="rating-5">5</label>
<input class="ratinginput2" id="rating2-4" name="rating2" type="radio" value="7" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--4" for="rating-4">4</label>
<input class="ratinginput2" id="rating2-3" name="rating2" type="radio" value="8" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--3" for="rating-3">3</label>
<input class="ratinginput2" id="rating2-2" name="rating2" type="radio" value="9" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--2" for="rating-2">2</label>
<input class="ratinginput2" id="rating2-1" name="rating2" type="radio" value="10" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--1" for="rating-1">1</label></div>

to

<div class="ratingControl2"><input class="ratinginput2" id="rating2-5" name="rating2" type="radio" value="6" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--5" for="rating2-5">5</label>
<input class="ratinginput2" id="rating2-4" name="rating2" type="radio" value="7" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--4" for="rating2-4">4</label>
<input class="ratinginput2" id="rating2-3" name="rating2" type="radio" value="8" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--3" for="rating2-3">3</label>
<input class="ratinginput2" id="rating2-2" name="rating2" type="radio" value="9" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--2" for="rating2-2">2</label>
<input class="ratinginput2" id="rating2-1" name="rating2" type="radio" value="10" />
<label class="filledStars ratingControl2-stars ratingControl2-stars--1" for="rating2-1">1</label></div>

Thanks for the quick help guys!!!

  • This is not the full answer to your question. Please either fully explain all necessary changes to your question's original code in your own answer, or delete it and pick an answer that complies with this requirement. – connexo Apr 08 '20 at 07:28