Using Data Attributes For A Dynamically Added Five-Star Rating System
Tags: javascript, beginners, json
Published: 2022-03-19 21:51:37

I learned something new! 

This blog post describes a new-to-me HTML attribute data, and how I used it to solve my five-star rating woes. 

I encountered some trouble while working on a JavaScript project. I was trying to build out a five-star rating system for data fetched from JSON server. 

A card was dynamically created for each object from the JSON server and appended to the page to display the JSON data.
Part of the card is a div containing five a tags with a rating star. I added an event listener to each star to listen for a click, and with JavaScript, I added a class name of ‘active’ to the clicked star and all the stars to its left.  Using CSS, anything with a class of ‘active’ was at full opacity.

The issue that I was having, was that I had gathered all my stars into an array and added the click event to all the stars. Unfortunately, when I clicked on a star, it did not differentiate between the stars on its parent card and the stars on previous cards, as all the stars were part of the same array. When I did a for loop counting the stars indices and console logging the index of a clicked star, it did not stop at five the way I had intended, but continued looping through all six cards, coming to a total of thirty!

I reached out to my awesome instructor Enoch, and he gave me the idea to use Data-* attribute. Datasets are an HTML attribute that can be used to store extra information on standard HTML elements which does not need to be seen or read. This makes it easy to differentiate between similar HTML elements that need to have the same class, but would be too annoying to make each its own id. What I did was add a data attribute called rating to each star as it is created, and assigned each star a number from 1-5. Now each card it its own parent node containing five unique stars, and the click event when rating is contained within its parent card.

``` javascript
star1.dataset.rating = 1
	  star2.dataset.rating = 2
	  star3.dataset.rating = 3
	  star4.dataset.rating = 4
	  star5.dataset.rating = 5

```

A data attribute is easy to add dynamically in JavaScript, but it must be noted that a data attribute is a string and must be parsed into an integer if you are storing numbers. 

```javascript
const addRating = (e) => {
	  console.log(e.target)
	  const starDiv = e.target.parentNode
	  const rating = parseInt(e.target.dataset.rating, 10)
	  
	  const aStars = starDiv.querySelectorAll('a')
	  
	  for (let i = 0; i < rating; i++) {
	    const a = aStars[i]
	    a.classList.add('active')
	  }
	}
```

Here is my function called by my event listener. When a star is clicked, it calls addRating, which loops through the stars and adds a class ‘active’ to the clicked star and all the stars with a rating number lower than the clicked star within its parent node!

Learning about using the data attribute is really exciting because there are so many ways to use this attribute. It is useful for any situation in which you would like to include extra data on an HTML element that does not need to be seen on the page. The only downside of using datasets is that it is currently unsupported on Internet Explorer.

Please let me know your feedback, I would love to hear what you think!