KaranjitFYP
KaranjitFYP

Reputation: 103

HTML: Submit star rating into my SQL database

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

Answers (1)

Emiel Zuurbier
Emiel Zuurbier

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

Related Questions