Created
December 4, 2021 08:09
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!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