Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

RayC's avatar
Level 10

AlpineJS star rating not displaying properly.

Hello all,

I am trying to show some star ratings using AlpineJS. Such as 4, 4.5. I can get the stars to show properly when the rating is a whole number like 4 with the last start grayed out using this code:

<div x-data="{ rating: {{ $dealer->averageRating(1) }} }">
    <div class="flex items-center">
        <template x-for="star in [1, 2, 3, 4, 5]" :key="star">
            <x-phosphor-star-fill class="w-4" x-bind:class="{'text-gray-300': star > rating}" />
        </template>
    </div>
</div>

Now when I adjust the code to take into consideration .5, it only displays 4 stars and not the last half star:

<div x-data="{ rating: 4.5 }">
    <div class="flex items-center">
        <template x-for="star in 5" :key="star">
            <template x-if="star <= rating">
                <x-phosphor-star-fill class="w-4 text-orange-500 fill-current" />
            </template>
            <template x-else-if="star - 0.5 === rating || (rating % 1 !== 0 && star === Math.ceil(rating))">
                <x-phosphor-star-half-fill class="w-4 text-orange-500 fill-current" />
            </template>
            <template x-else>
                <x-phosphor-star-fill class="w-4 text-gray-300 fill-current" />
            </template>
        </template>
    </div>
</div>

I have also tried it this way:

<div x-data="{ rating: 4.5 }">
    <div class="flex items-center">
        <template x-for="star in [1, 2, 3, 4, 5]" :key="star">
            <template x-if="star <= rating">
                <x-phosphor-star-fill class="w-4 text-orange-500 fill-current" />
            </template>
            <template x-else-if="star - 0.5 === rating || (rating % 1 !== 0 && star === Math.ceil(rating))">
                <x-phosphor-star-half-fill class="w-4 text-orange-500 fill-current" />
            </template>
            <template x-else>
                <x-phosphor-star-fill class="w-4 text-gray-300 fill-current" />
            </template>
        </template>
    </div>
</div>

I get no errors on the page and none in the console. Thank you in advance for your help.

0 likes
1 reply
RayC's avatar
RayC
OP
Best Answer
Level 10

After playing around with it for a bit more, I have found the solutiin:

<div x-data="{ rating: {{ $slot }} }">
    <div class="flex items-center">
        <template x-for="star in [1, 2, 3, 4, 5]" :key="star">
            <template x-if="star <= rating">
                <x-phosphor-star-fill class="w-4" />
            </template>
        </template>
        <template x-for="star in [1, 2, 3, 4, 5]" :key="star">
            <template x-if="rating === star - 0.5 ||  rating > star - 0.5 && star > rating">
                <x-phosphor-star-half-fill class="w-4" />
            </template>
        </template>
        <template x-for="star in [1, 2, 3, 4, 5]" :key="star">
            <template x-if="star - 0.5 > rating && star > rating">
                <x-phosphor-star-fill class="w-4 text-gray-300" />
            </template>
        </template>
    </div>
</div>

There may be a better solution, but this one works as expected. If you a better way, please let me know.

Please or to participate in this conversation.