简体   繁体   中英

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();

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM