Guilhem V
Guilhem V

Reputation: 381

Laravel - Star rating - Optimization?

It's not a problem in fact, but I would like to know if it is possible to optimise the code below.

It's a simple code to show the star rating mark which is in the db.

I searched and tried with @foreach, but can't figure it out.

Code:

<span class="review-stars" style="color: #1e88e5;">
<!-- ////////////// STAR RATE CHECKER ////////////// -->
    @if($review->rate <= 0)
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
    @elseif($review->rate === 1)
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
    @elseif($review->rate === 2)
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
    @elseif($review->rate === 3)
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
    @elseif($review->rate === 4)
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star-o" aria-hidden="true"></i>
    @elseif($review->rate >= 5)
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
        <i class="fa fa-star" aria-hidden="true"></i>
    @endif
    <!-- ///////////////////////////////////////////// -->
</span>

When $review->rate <= 0 enter image description here

When $review->rate === 3 enter image description here

When $review->rate >= 5 enter image description here

Upvotes: 1

Views: 12198

Answers (5)

mickmackusa
mickmackusa

Reputation: 47992

Don't Repeat Yourself. Loop 5 times and write a condition to check if the star should be empty.

Code: (Demo: https://3v4l.org/Tj31J )

$review = (object)['rate' => 3];
for ($i = 0; $i < 5; ++$i) {
    echo '<i class="fa fa-star' , ($review->rate <= $i ? '-o' : '') , '" aria-hidden="true"></i>';
}

Output:

<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<i class="fa fa-star-o" aria-hidden="true"></i>
<i class="fa fa-star-o" aria-hidden="true"></i>

I don't code in Laravel, correct me if this syntax is flawed:

@for ($i = 0; $i < 5; ++$i)
    <i class="fa fa-star{{ $review->rate <= $i ? '-o' : '' }}" aria-hidden="true"></i>
@endfor

If you want to incorporate half-empty (aka half-full) stars, just add another condition. The same design logic applies, add one more condition to check if the star should be halved. Here is a full battery of valid ratings tested:

Code (See the Demo for verbose output: https://3v4l.org/r4c6R )

$reviews = [
    (object)['rate' => 0],
    (object)['rate' => .5],
    (object)['rate' => 1],
    (object)['rate' => 1.5],
    (object)['rate' => 2],
    (object)['rate' => 2.5],
    (object)['rate' => 3],
    (object)['rate' => 3.5],
    (object)['rate' => 4],
    (object)['rate' => 4.5],
    (object)['rate' => 5]
];
foreach ($reviews as $review) {
    for ($i = 0; $i < 5; ++$i) {
        echo '<i class="fa fa-star' ,
            ($review->rate == $i + .5 ? '-half' : '') ,
            ($review->rate <= $i ? '-o' : '') ,
            '" aria-hidden="true"></i>';
        echo "\n";
    }
    echo "\n";
}

If you don't understand the inline conditional syntax, google is only a click away.

Upvotes: 3

Hikafer tsamsiyu
Hikafer tsamsiyu

Reputation: 14

In controller round the rating to 0.5

$rating = round($number*2)/2;

Pass the rating to the view and add this code:

    @for($x = 5; $x > 0; $x--)
    @php 
        if($rating > 0.5){
            echo '<i class="fas fa-star"></i>';
        }elseif($rating <= 0 ){
            echo '<i class="far fa-star"></i>';
        }else{
            echo '<i class="fas fa-star-half-alt"></i>';
        }
        $rating--;      
    @endphp
@endfor

Upvotes: 0

Matin malek
Matin malek

Reputation: 81

You can do it by following code

@foreach(range(1,5) as $i)
    @if($rating >0)
        @if($rating >0.5)
            <i class="fa fa-star"></i>
        @else
            <i class="fa fa-star-half-o"></i>
        @endif
    @else
        <i class="fa  fa-star-o"></i>
    @endif
    <?php $rating--; ?>
@endforeach

Upvotes: 3

Tpojka
Tpojka

Reputation: 7111

Try this way:

<i class="fa fa-star{{ $review->rate <= 0 ? '-o' : '' }} aria-hidden="false"></i><!-- First case is for 0 and 1 case or empty and filled star -->
<i class="fa fa-star{{ $review->rate >= 2 ? '-o' : '' }} aria-hidden="false"></i>
<i class="fa fa-star{{ $review->rate >= 3 ? '-o' : '' }} aria-hidden="false"></i>
<i class="fa fa-star{{ $review->rate >= 4 ? '-o' : '' }} aria-hidden="false"></i>
<i class="fa fa-star{{ $review->rate >= 5 ? '-o' : '' }} aria-hidden="false"></i>

Upvotes: 0

Faramarz Salehpour
Faramarz Salehpour

Reputation: 601

I think that's all you need to do. No loops needed. Just make sure the rate value is between 0 and 5 (inclusive) before passing it to the view.

{!! str_repeat('<i class="fa fa-star" aria-hidden="true"></i>', $review->rate) !!}
{!! str_repeat('<i class="fa fa-star-o" aria-hidden="true"></i>', 5 - $review->rate) !!}

Upvotes: 4

Related Questions