I want to make a simple rating selection with star icon from enum in the form of a radio_button.
my model:
enum rating: %i(1 2 3 4 5 6 7 8 9 10)
and my view:
= form_with model: @rating do |f|
.form-group
label.input-label.text-white = t(".title")
- Rating.ratings.keys.each do |rating|
= f.radio_button(:rating, rating) do |star_icon|
= star_icon.label { "i fa fa-star" star_icon.radio_button }
= f.submit t("submit")
Honestly it looks scary, so I want to apply a style to make it look like a real rating. The radio buttons on the left and right are just html icons
li
i.fa.fa-star title=("Rate 10")
li
i.fa.fa-star title=("Rate 9")
li
i.fa.fa-star title=("Rate 8")
li
i.fa.fa-star title=("Rate 7")
li
i.fa.fa-star title=("Rate 6")
li
i.fa.fa-star title=("Rate 5")
li
i.fa.fa-star title=("Rate 4")
li
i.fa.fa-star title=("Rate 3")
li
i.fa.fa-star title=("Rate 2")
li
i.fa.fa-star title=("Rate 1")
CodePudding user response:
Honestly I would take a completely different approach. There isn't really a good reason to use an enum column to save a rating value, it just needs to be an integer.
To capture the value in the view, a radio button is not the best look, I would use a little javascript (shown with jQuery here) and a little css to render a more typical rating selector (written here in haml syntax):
=form_for @rating, method: :post, remote: true do |f|
= f.hidden_field :rating, id: :rating
- (1..10).each do |i|
.star{data: {rating: i}}
:css
.star{
display: inline-block;
}
.star::before{
content: '\2606'
}
.star.selected::before{
content: '\2605';
}
:javascript
let selectRating = (event)=>{
let target = $(event.target);
let rating = parseInt(target.data('rating'));
$('.star').each((i,el)=>{
if(i<rating){
$(el).addClass('selected');
}else{
$(el).removeClass('selected');
}
})
$('#rating').attr('value',rating);
$('form').submit();
}
$('body').on('click', '.star',selectRating)
it will look like this
Now when you click on one of the stars, the clicked star and all stars left of it become 'solid' and all the stars right of it become 'empty'. Also the value of the hidden field is set to the selected rating, so you can submit the form and save the rating on the backend.