Skip to content

Instantly share code, notes, and snippets.

@nfreear
Created December 4, 2021 08:09
Show Gist options
  • Select an option

  • Save nfreear/fd080b4e49c34578baa9ef546ee03c90 to your computer and use it in GitHub Desktop.

Select an option

Save nfreear/fd080b4e49c34578baa9ef546ee03c90 to your computer and use it in GitHub Desktop.
Javascript Web Component to implement a star-rating widget as a set of radio buttons.
<!doctype html> <title> My radio star rating </title>
<style>
:root {
--star-rating-size: 4rem;
--no-star-url: url(https://upload.wikimedia.org/wikipedia/commons/e/e7/Empty_Star.svg);
--star-url: url(https://upload.wikimedia.org/wikipedia/commons/3/34/Red_star.svg);
}
/* Reset */
fieldset { border: none; padding: 0; }
fieldset legend { position: relative; left: -1rem; }
label i { font-style: normal; }
input { width: 2rem; }
.radio-star-rating-set label {
background-image: var(--star-url);
background-repeat: no-repeat;
background-size: contain;
border: 1px solid #ddd;
border-radius: 50%;
cursor: pointer;
display: inline-block;
font-size: x-small;
margin: 0;
height: var(--star-rating-size);
width: var(--star-rating-size);
}
.radio-star-rating-set label:hover,
.radio-star-rating-set label.focused {
X-outline: 1px solid blue;
box-shadow: 0 0 4px 2px blue;
}
.radio-star-rating-set legend,
.X-radio-star-rating-set [ type = radio ] {
overflow: hidden;
height: 0;
width: 0;
}
</style>
<h1> My radio star rating </h1>
<p><a href="#">Before</a></p>
<!-- <div>Align</div> -->
<form>
<p>
<label for="rating-1"> How would you rate the quality of our service? </label>
<input id="rating-1" type="" data-stars="" is="my-star-rating" />
</p>
<fieldset class="radio-star-rating-set" data-stars="">
<legend> How would you rate the quality of our service? </legend>
<label class="star-1"><input type="radio" name="rsrg-1" data-star="1" /><i> 1 star </i></label>
<label class="star-2"><input type="radio" name="rsrg-1" data-star="2" /><i> 2 stars </i></label>
<label class="star-3"><input type="radio" name="rsrg-1" data-star="3" /><i> 3 stars </i></label>
<label class="star-4"><input type="radio" name="rsrg-1" data-star="4" /><i> 4 stars </i></label>
<label class="star-5"><input type="radio" name="rsrg-1" data-star="5" /><i> 5 stars </i></label>
</fieldset>
</form>
<!-- <div>Align</div> -->
<p><a href="#">After</a></p>
<script>
/* class MyStarRatingElement extends HTMLElement {
constructor() {
super();
}
} */
const RATING = document.querySelector('#rating-1');
const STARS = document.querySelector('.radio-star-rating-set');
const LABELS = STARS.querySelectorAll('label');
STARS.addEventListener('click', ev => {
// const RADIO = ev.target;
const LABEL = ev.target.parentElement;
const VALUE = parseInt(ev.target.getAttribute('data-star'));
if (ev.target.nodeName !== 'INPUT') { // NaN.
[...LABELS].map(label => label.classList.remove('focused'));
return;
}
RATING.value = VALUE;
RATING.setAttribute('data-stars', VALUE);
STARS.setAttribute('data-stars', VALUE);
[...LABELS].map(label => label.classList.remove('focused'));
LABEL.classList.add('focused');
console.log('Star rating. Click:', VALUE, VALUE ? 'ok':'err', ev);
});
</script>
<pre>
NDF, 04-Dec-2021.
</pre>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment