Reputation: 103
I currently have a working review form that the user can write a review about a hotel. So far it takes in a title and body but i now wish to implement a star rating so the user selects a rating and it will submit to my database. I currently have the code where the user can submit the title and body, however the star rating does not submit and does not submit to my database. Can anyone advise ?
ReviewController.php
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required' ,
'body' => 'required' ,
'post_id' => 'required'
]);
$review = new Review;
$review->title = $request->input('title');
$review->body = $request->input('body');
$review->rating = $request->input('rating');
$review->post_id = $request['post_id'];
$review->save();
return redirect('/posts')->with('success', 'post created');
}
Show.blade.php
<h1>Reviews</h1>
@if(count($review) > 1)
@foreach($review as $reviews)
<div class= "well">
<h3><a href="/reviews/{{$reviews->title}}">{{$reviews->title}} </a>{{$reviews->rating}}</h3><small>{{$reviews->created_at}}</small><br>
<small>{{$reviews->body}}</small>
<br>
<br>
</div>
@endforeach
@else
</p>no posts found</p>
@endif
@endsection
Javascript:
var count;
function starmark(item)
{
count=item.id[0];
sessionStorage.starRating = count;
var subid= item.id.substring(1);
for(var i=0;i<5;i++)
{
if(i<count)
{
document.getElementById((i+1)+subid).style.color="orange";
}
else
{
document.getElementById((i+1)+subid).style.color="black";
}
}
}
When i submit this to my database, the values appear as NULL, however i want them to have a value from 1-5.
Upvotes: 1
Views: 1970
Reputation: 20944
While <input>
elements can send data in a form, <span>
elements cannot. Now you are using a function in JavaScript to simulate this kind of behavior by trying to get the value from the hovered or clicked span. The sessionStorage.starRating = count
should be sessionStorage.setItem('starRating', count)
to store the value into the session storage. But that's not the culprit.
Instead of using <span>
elements, use <input type="radio">
elements to indicate the rating the user gives. While styling may look difficult, it can be fairly easy by using the <label>
element as the styling point. When you connect the <label>
with the for
attribute to the id of the <input>
element it belongs to, it becomes clickable. Meaning that whenever I click the label, the input will be clicked as well and will therefor be selected.
So you hide the input and style the label. And in CSS you say how the clicked label is supposed to look based on the currently selected input. The :checked
psuedo selector is a real lifesaver here.
Putting this all together in your form makes the currently selected radio button to be send to the server with the proper name
and value
pair without having to do any JavaScript.
Check out the snippet below to see it work. The JavaScript part can be ignored as it is merely a demonstration.
/**
* For demonstration purposes.
* Logs the currently submitted 'rating' value.
*/
const form = document.querySelector('form');
form.addEventListener('submit', event => {
const formData = new FormData(event.target);
const rating = formData.get('rating');
console.log(rating);
event.preventDefault();
});
.star-input {
display: none;
}
.star {
color: gold;
}
.star-input:checked + .star ~ .star {
color: white;
}
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css">
<form>
<input type="radio" class="star-input" name="rating" id="star-1" value="1">
<label for="star-1" class="star"><i class="fas fa-star"></i></label>
<input type="radio" class="star-input" name="rating" id="star-2" value="2">
<label for="star-2" class="star"><i class="fas fa-star"></i></label>
<input type="radio" class="star-input" name="rating" id="star-3" value="3">
<label for="star-3" class="star"><i class="fas fa-star"></i></label>
<input type="radio" class="star-input" name="rating" id="star-4" value="4">
<label for="star-4" class="star"><i class="fas fa-star"></i></label>
<input type="radio" class="star-input" name="rating" id="star-5" value="5" checked>
<label for="star-5" class="star"><i class="fas fa-star"></i></label>
<button type="submit">Send</button>
</form>
Upvotes: 1