user11710915
user11710915

Reputation: 434

How to display rating stars Laravel and Ajax

I have created a review system which allows a user to add a review in a product and display the rating stars. So if a user rate a product with 4 it should display 4 full stars and one empty star(just like other review system). How can I loop and display each rating stars according to users reviews?

This is the data received from controller (console.log())

data: Array(2)
0: "4" //This is the rating for user 1
1: "3"  // This is for user 2
length: 2

Controller

 $products = Product::where('id','=',$id)->with('reviews.user')->get();
        $data = array(); 
        foreach ($products as $product)
        {
        foreach ($product->reviews as $review){
        $data []= $review->rating; 
        }
        }
        return response()->json(['code' => 200,'data' => $data]);

Ajax

  function UserRateStars() {
  $.ajax({
    type: "GET",
    url: '{{route('userRate.stars ', $id)}}',
    success: function(data) {
        document.getElementById("UserRateStars").innerHTML = UserRateStars(3.6);

            // Round to nearest half
            var rating = Math.round(data * 2) / 2;
            let output = [];
            console.log(data);
            // Append all the filled whole stars
            for (var i = rating; i >= 1; i--)
                output.push('<div >full star</div>&nbsp;');

            // If there is a half a star, append it
            if (i == .5) output.push('<div >half star</div>&nbsp;');

            // Fill the empty stars
            for (let i = (5 - rating); i >= 1; i--)
                output.push('<div>empty star</div>&nbsp;');

            return output.join('');

        }
});

}
UserRateStars();

Upvotes: 0

Views: 1895

Answers (2)

Mohammedshafeek C S
Mohammedshafeek C S

Reputation: 1943

Here the alteration needed in your code..

<script type="text/javascript">
function UserRateStars() {
    $.ajax({
        type: "GET",
        url: '{{route('userRate.stars ', $id)}}',
        success: function(data) { 
            var html = [];                      
            data.data.forEach(function (item, index) {
                var newDiv = document.createElement("div");
                newDiv.setAttribute("id", "user"+index);
                newDiv.innerHTML = SingleUserRateStars(item); 
                html.push(newDiv.outerHTML);
            });
            document.getElementById("UserRateStars").innerHTML = html.join('');                    
        }
    });
}
UserRateStars();

function SingleUserRateStars(rating) {

    // Round to nearest half
    rating = Math.round(rating * 2) / 2;
    let output = [];
    console.log(rating);
    // Append all the filled whole stars
    for (var i = rating; i >= 1; i--)
        output.push('<div style="display:inline-block" >full star</div>&nbsp;');

    // If there is a half a star, append it
    if (i == .5) output.push('<div style="display:inline-block" >half star</div>&nbsp;');

    // Fill the empty stars
    for (let i = (5 - rating); i >= 1; i--)
        output.push('<div style="display:inline-block" >empty star</div>&nbsp;');

    return output.join('');

}        
</script>

I assume the inner function you used is to generate individual user's rating and user data you are generating from the server as array. For example ["2","4","4.5"]

I split it to outside and looped each user rating and wrapped each rating inside one div and appended to your target div. Hope this could help you.

Upvotes: 1

Ahmed Sunny
Ahmed Sunny

Reputation: 2243

when you copy something from internet, first take a look at it and see how it flows, the flow is clearly wrong, it would have given error.

first: separate functions 1 to get userRateStars

second to load it, you can do it by event or just make a function and call it from where you want

  function UserRateStars(rate) {

      // Round to nearest half
            var rating = Math.round(rate * 2) / 2;
            let output = [];
            console.log(rating);
            // Append all the filled whole stars
            for (var i = rating; i >= 1; i--)
                output.push('<div >full star</div>&nbsp;');

            // If there is a half a star, append it
            if (i == .5) output.push('<div >half star</div>&nbsp;');

            // Fill the empty stars
            for (let i = (5 - rating); i >= 1; i--)
                output.push('<div>empty star</div>&nbsp;');

            return output.join('');
}

// load ratings just say by click
 //  function loadRateStars() { // use this if you dont want event
   $('#btn_load_rating').on('click' , function() {
     $.ajax({
    type: "GET",
    url: '{{route('userRate.stars ', $id)}}',
    success: function(data) {
         // if you see in below line you are calling userratestars with 3.6
       // document.getElementById("UserRateStars").innerHTML = UserRateStars(3.6);
         // use it like this and return will show stars
        document.getElementById("UserRateStars").innerHTML = UserRateStars(data);

        }
    });

 })

i think it should work now

Upvotes: 1

Related Questions