Creating a Custom Rating System with JavaScript

An image that is being used for an article discussing a custom rating system created with JavaScript. The image depicts a stylised visual representation of coding elements without any text or human figures. It features a schematic JavaScript logo: a lightweight, yellow-golden geometric shape, composed of swirling circular patterns. Next to it, there are five star symbols, each one progressively filling up from empty to solid, demonstrating the rating scale. None of the items have any brand names or logos on them.

Why Create a Custom Rating System with JavaScript?

Creating a custom rating system with JavaScript allows you complete control over the design and functionality of your rating components.

With a custom solution, you can tailor the appearance to match your site’s theme, include unique features, and ensure the system integrates seamlessly with your backend.

Off-the-shelf solutions may not provide the flexibility you require.

TLDR: Implementing a Custom Rating System in JavaScript

Here’s a quick example of how to create a 5-star rating system using pure JavaScript:


// Add HTML for the rating star

// Add CSS for the star rating

// JavaScript code for rating system

In this example, we create a simple 5-star rating system using plain JavaScript, HTML, and CSS.

Setting Up the HTML Structure

First, we need to set up the HTML structure for our rating system.

We'll create a div element to hold our stars:

This div will serve as the container for our rating stars.

We can use JavaScript to generate the stars dynamically inside this container.

Styling the Stars with CSS

Next, we'll add some CSS to style the stars so that they resemble a typical rating system.

Here's a simple CSS snippet:

The .star class adds basic styles to the stars, such as setting the font size and changing the cursor to a pointer.

The .star.rated class changes the color of the stars to gold when they are rated.

Using JavaScript to Add Interactivity

To add interactivity, we'll write JavaScript that dynamically generates the stars and handles the rating logic.

First, we'll use JavaScript to create 5 stars and append them to the div:


document.addEventListener('DOMContentLoaded', () => {
const ratingDiv = document.getElementById('rating');
const stars = Array(5).fill().map((_, i) => {
const star = document.createElement('span');
star.textContent = '★';
star.classList.add('star');
ratingDiv.appendChild(star);
return star;
});
});

We use Array(5).fill().map(… to create an array of 5 elements and generate a star for each element.

Each star is represented by a span element with the star class and is appended to the rating div.

Handling User Interaction

Now, we need to handle user interactions, such as clicking on a star to set the rating.

We'll add event listeners to each star for the click event:


stars.forEach((star, index) => {
star.addEventListener('click', () => rateStar(index + 1));
});

When a star is clicked, we call the rateStar function, passing the index of the clicked star plus one.

The rateStar function handles updating the rating and visually marking the rated stars:


function rateStar(rating) {
stars.forEach((star, index) => {
star.classList.toggle('rated', index < rating); }); console.log(`User rated: ${rating} stars`); }

This function iterates over all the stars and toggles the rated class on the stars that are less than the current rating.

We also log the rating to the console for debugging purposes.

Ensuring Accessibility

Making your custom rating system accessible ensures that it can be used by everyone, including those with disabilities.

Here are some tips for making your rating system accessible:

  • Use appropriate ARIA roles and properties.
  • Provide keyboard navigation.
  • Ensure color contrast.

Adding ARIA Roles

Adding ARIA roles and properties helps screen readers understand the role and state of each element.

Here's how you can enhance the accessibility of your rating system:

Star 1

Each star should have the role="radio" and aria-checked attributes to indicate its state:


star.setAttribute('role', 'radio');
star.setAttribute('aria-checked', 'false');

Update the rateStar function to set the aria-checked attribute:


function rateStar(rating) {
stars.forEach((star, index) => {
star.classList.toggle('rated', index < rating); star.setAttribute('aria-checked', index < rating); }); }

Providing Keyboard Navigation

Adding keyboard navigation ensures that users can interact with the rating system using the keyboard.

Handle the keydown event on each star to support keyboard navigation:


stars.forEach(star => {
star.setAttribute('tabindex', 0);
star.addEventListener('keydown', event => {
if (event.key === 'Enter' || event.key === ' ') {
rateStar(stars.indexOf(star) + 1);
}
});
});

Ensuring Color Contrast

To ensure color contrast, choose colors that meet the WCAG standards for contrast ratio.

Use tools like the WebAIM Contrast Checker to test your color choices.

Deploying Your Custom Rating System

After creating and testing your custom rating system, you are ready to deploy it.

Ensure your system is well-documented and include instructions for integrating it into your site or application.

Common Pitfalls and How to Avoid Them

Creating a custom rating system presents some challenges. Here are common pitfalls and how to avoid them:

Overcomplicating the Design

Do not add unnecessary features that can overcomplicate the code.

Keep the design simple and intuitive.

Ignoring Accessibility

Ensure that your rating system is accessible to all users by using ARIA roles and keyboard navigation.

Lack of Testing

Test your rating system across different browsers and devices to ensure compatibility.

FAQs

How can I change the number of stars in the rating system?

You can change the number of stars by modifying the array length in the JavaScript code:

const stars = Array(10).fill().map((_, i) => {...

Can I use images instead of text for the stars?

Yes, you can replace the text content of the star span with an image element.

How do I make the rating persistent?

Save the rating to a backend database and load it when the page is loaded.

Extending JavaScript to Save the Rating

To make the rating persistent, you'll need to save the user's rating to a backend database.

This will allow the rating to be loaded when the page is refreshed or revisited.

Using Local Storage

As a simple solution, you can use the browser's local storage to save the rating.

Here's an example of how to modify the rateStar function to save the rating:


function rateStar(rating) {
stars.forEach((star, index) => {
star.classList.toggle('rated', index < rating); star.setAttribute('aria-checked', index < rating); }); localStorage.setItem('rating', rating); console.log(`User rated: ${rating} stars`); }

To load the stored rating when the page loads, modify the JavaScript to check for a stored rating:


document.addEventListener('DOMContentLoaded', () => {
const savedRating = localStorage.getItem('rating');
if (savedRating) {
rateStar(parseInt(savedRating));
}
});

This simple approach works well for client-side data storage but won't persist across different devices.

Saving to a Backend Database

For a more robust solution, save the rating to a backend database.

Here's a basic example using Fetch API to send the rating to a server:


function rateStar(rating) {
stars.forEach((star, index) => {
star.classList.toggle('rated', index < rating); star.setAttribute('aria-checked', index < rating); }); fetch('/api/save-rating', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ rating }), }).then(response => {
if (response.ok) {
console.log(`Rating saved: ${rating} stars`);
}
});
}

The server should handle the "/api/save-rating" endpoint to save the rating to a database.

Loading the Rating from the Backend

To load the rating from the backend when the page loads, fetch the rating from the server:


document.addEventListener('DOMContentLoaded', () => {
fetch('/api/get-rating')
.then(response => response.json())
.then(data => {
if (data.rating) {
rateStar(data.rating);
}
});
});

Ensure the server responds with the stored rating in JSON format.

Handling Different States

When creating a rating system, consider how to handle different states such as hover, focus, and disabled.

Adding Hover Effect

To provide feedback as users hover over the stars, add a hover effect using JavaScript:


stars.forEach((star, index) => {
star.addEventListener('mouseenter', () => highlightStars(index + 1));
star.addEventListener('mouseleave', () => clearHighlight());
});
function highlightStars(count) {
stars.forEach((star, index) => {
star.classList.toggle('highlighted', index < count); }); } function clearHighlight() { stars.forEach(star => star.classList.remove('highlighted'));
}

Update the CSS to style the .highlighted class:

This provides immediate visual feedback when users hover over the stars.

Focusing on Accessibility

Make sure the rating system is accessible by adding focus styles:

Example CSS for focus styles:

This improves accessibility for keyboard users.

Disabling the Rating System

Sometimes, you might need to disable the rating system, perhaps when the user already rated.

Here is an approach to disable stars dynamically:


function disableRating() {
stars.forEach(star => {
star.classList.add('disabled');
star.setAttribute('tabindex', -1);
star.removeEventListener('click', rateStar);
});
}

Update the CSS to style the .disabled class:

Call the disableRating function when needed to disable the stars.

Optimizing Your Rating System

For better performance and user experience, optimize your rating system.

Improving Performance

When dealing with a large number of stars, performance can become an issue.

Use requestAnimationFrame for smoother interactions:


function rateStar(rating) {
requestAnimationFrame(() => {
stars.forEach((star, index) => {
star.classList.toggle('rated', index < rating); star.setAttribute('aria-checked', index < rating); }); localStorage.setItem('rating', rating); console.log(`User rated: ${rating} stars`); }); }

This ensures a smoother and more responsive user experience.

Improving UX with Animations

Adding animations can enhance the user experience.

Here's an example of animating the stars when rated:

Animations make the rating system more engaging.

Clear Button to Reset Rating

Add a clear button to allow users to reset their rating:



document.getElementById('clear-rating').addEventListener('click', () => {
stars.forEach(star => {
star.classList.remove('rated');
star.setAttribute('aria-checked', 'false');
});
localStorage.removeItem('rating');
console.log('Rating cleared');
});

This gives users flexibility to change or clear their rating.

Common Issues and How to Fix Them

Issues with Hover Effects

Hover effects may not work on touch devices.

Solution: Use focus styles to provide similar feedback for touch users.

Rating Persistence

Users might lose their rating if not implemented properly.

Solution: Always test the persistence mechanism and ensure data integrity.

Cross-browser Compatibility

The rating system might behave differently across browsers.

Solution: Test your system on multiple browsers and addresses compatibility issues.

How can I change the number of stars in the rating system?

You can change the number of stars by modifying the array length in the JavaScript code:

const stars = Array(10).fill().map((_, i) => {...

Can I use images instead of text for the stars?

Yes, you can replace the text content of the star span with an image element.

How do I make the rating persistent?

Save the rating to a backend database and load it when the page is loaded.

Is it possible to make the rating system accessible?

Yes, use ARIA roles, keyboard navigation, and ensure color contrast for accessibility.

How can I add animations to the rating stars?

Add CSS transitions to the .rated class for smooth animations:

.star.rated { transition: color 0.3s ease-in-out; }

What are common issues with custom rating systems?

Common issues include hover effects not working on touch devices and rating persistence problems.

How do I test the rating system across different browsers?

Use browser testing tools and manually check the system on different browsers to ensure compatibility.

Is it possible to disable the rating system?

Yes, you can add a .disabled class and remove event listeners to disable it:

function disableRating() { stars.forEach(star => { star.classList.add('disabled'); star.setAttribute('tabindex', -1); star.removeEventListener('click', rateStar); }); }

Shop more on Amazon