Reputation: 434
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> ');
// If there is a half a star, append it
if (i == .5) output.push('<div >half star</div> ');
// Fill the empty stars
for (let i = (5 - rating); i >= 1; i--)
output.push('<div>empty star</div> ');
return output.join('');
}
});
}
UserRateStars();
Upvotes: 0
Views: 1895
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> ');
// If there is a half a star, append it
if (i == .5) output.push('<div style="display:inline-block" >half star</div> ');
// Fill the empty stars
for (let i = (5 - rating); i >= 1; i--)
output.push('<div style="display:inline-block" >empty star</div> ');
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
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> ');
// If there is a half a star, append it
if (i == .5) output.push('<div >half star</div> ');
// Fill the empty stars
for (let i = (5 - rating); i >= 1; i--)
output.push('<div>empty star</div> ');
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