In this blog post, we'll guide you through creating an interactive star rating system using Alpine.js and Tailwind CSS. . This feature not only enhances user experience but also provides valuable visual feedback and meaningful labels during the rating process.
The Goal
We aim to implement a star rating system that:- Highlights star label on hover and click.
- Displays a corresponding label for the rating (e.g., "Terrible" for 1 star, "Great" for 5 stars).
The Code
Below is the code snippet used inapp/design/frontend/<Vendor>/<Theme>/Magento_Review/templates/form.phtml
In the parent <div> containing the star ratings, include the following code inside the x-data.
x-data="
{
clickedRatingId: 0,
hoveredRatingId: 0,
ratings: [
{ amount: 1, label: 'Terrible' },
{ amount: 2, label: 'Bad' },
{ amount: 3, label: 'Okay' },
{ amount: 4, label: 'Good' },
{ amount: 5, label: 'Great' },
],
get currentLabel() {
const ratingId = this.hoveredRatingId || this.clickedRatingId || 0;
return ratingId
? this.ratings[ratingId - 1]?.label
: 'Please Rate!';
}
}"
Within the foreach loop, add both @mouseover and @mouseleave events alongside the @click event.
@mouseover="hoveredRatingId = <?= (int)$iterator ?> || 0" @mouseleave="hoveredRatingId = 0"In the star icon’s parent element, ensure that both the
hover ID and the default value of 0 along with the click ID are included.
<= (hoveredRatingId || clickedRatingId || 0)Add the following code after the foreach loop to display the label.
<div class="ml-4 text-sm text-gray-600" x-show="currentLabel" x-text="currentLabel"></div>After making these changes, remember to run the following command in your root directory to clear the cache:
bin/magento cache:clean
Code Explanation
ThecurrentLabel property dynamically updates based on the hovered or clicked star, displaying contextual feedback for the user.
const ratingId:
- This simplifies the conditional logic by storing the resolved rating ID.
ratingId ? ... : 'Please Rate!': - If a valid rating ID exists (
ratingIdis not0), retrieve the corresponding label. - If ratingId is 0, return the fallback text "Please Rate!".
@mouseover and @mouseleave events handle the hover state