使用 jQuery 星形选择器的 Rails 表单

Posted

技术标签:

【中文标题】使用 jQuery 星形选择器的 Rails 表单【英文标题】:Rails form using a jQuery star selector 【发布时间】:2021-07-06 20:21:29 【问题描述】:

我有一个用于创建推荐的 rails 表单。 目前我正在使用表单 number_field 来选择从 1 到 5 的星级。

我有一个 jQuery 星级选择器,我想在表单上使用它,但不确定在提交表单时如何将数据值保存为星级。 有没有办法做到这一点?

表格

<h1>Comment as <%= current_user.first_name %> <%= current_user.last_name %></h1>
<div class="border border-grey-light rounded" style ="padding: 10px;">
  <%= image_tag current_user.avatar_thumbnail, class: "avatar", alt: "avatar" %>
  <%= form_with model: @testomonial do |f| %>
    <div class="mb-3">
      <%= f.label :review, class: "label" %>
      <%= f.text_field :body, class: "form-control", placeholder: "Write review in here" %>
    </div>
    <div class="mb-3">
      <%= f.label :stars, class: "label" %>
      <%= f.number_field :star, in: 1..5, class: "form-control" %>
    </div>
    <div class="mb-3">
      <%= f.submit class: "btn btn-primary text-base py-1.5 px-5", value: "Post testomonial" %>
    </div>
  <% end %>
</div>

星级选择器

<div class='rating-stars text-center'>
  <ul id='stars'>
    <li class='star' title='Poor' data-value='1'>
      <i class='fa fa-star fa-fw'></i>
    </li>
    <li class='star' title='Fair' data-value='2'>
      <i class='fa fa-star fa-fw'></i>
    </li>
    <li class='star' title='Good' data-value='3'>
      <i class='fa fa-star fa-fw'></i>
    </li>
    <li class='star' title='Excellent' data-value='4'>
      <i class='fa fa-star fa-fw'></i>
    </li>
    <li class='star' title='WOW!!!' data-value='5'>
      <i class='fa fa-star fa-fw'></i>
    </li>
  </ul>
</div>

用于星形选择器的 jQuery

$(document).ready(function()

  /* 1. Visualizing things on Hover - See next part for action on click */
  $('#stars li').on('mouseover', function()
    var onStar = parseInt($(this).data('value'), 10); // The star currently mouse on

    // Now highlight all the stars that's not after the current hovered star
    $(this).parent().children('li.star').each(function(e)
      if (e < onStar) 
        $(this).addClass('hover');
      
      else 
        $(this).removeClass('hover');
      
    );

  ).on('mouseout', function()
    $(this).parent().children('li.star').each(function(e)
      $(this).removeClass('hover');
    );
  );


  /* 2. Action to perform on click */
  $('#stars li').on('click', function()
    var onStar = parseInt($(this).data('value'), 10); // The star currently selected
    var stars = $(this).parent().children('li.star');

    for (i = 0; i < stars.length; i++) 
      $(stars[i]).removeClass('selected');
    

    for (i = 0; i < onStar; i++) 
      $(stars[i]).addClass('selected');
    

    // JUST RESPONSE (Not needed)
    var ratingValue = parseInt($('#stars li.selected').last().data('value'), 10);
    var msg = "";
    if (ratingValue > 1) 
        msg = "Thanks! You rated this " + ratingValue + " stars.";
    
    else 
        msg = "We will improve ourselves. You rated this " + ratingValue + " stars.";
    
    responseMessage(msg);

  );


);

已编辑的表单 - 工作

<%= form_with model: @testomonial do |f| %>
  <div class="mb-3">
    <%= f.label :review, class: "label" %>
    <%= f.text_field :body, class: "form-control", placeholder: "Write review in here" %>
  </div>
  <div class="mb-3">
    <%= f.label :stars, class: "label" %>
    <%= f.hidden_field :star %>
    <!-- star selector: -->
    <div class='rating-stars text-center'>
      <ul id='stars'>
        <li class='star' data-value='1'>
          <i class='fa fa-star fa-fw'></i>
        </li>
        <li class='star' data-value='2'>
          <i class='fa fa-star fa-fw'></i>
        </li>
        <li class='star' data-value='3'>
          <i class='fa fa-star fa-fw'></i>
        </li>
        <li class='star' data-value='4'>
          <i class='fa fa-star fa-fw'></i>
        </li>
        <li class='star' data-value='5'>
          <i class='fa fa-star fa-fw'></i>
        </li>
      </ul>
    </div>
  </div>
  <div class="mb-3">
    <%= f.submit class: "btn btn-primary text-base py-1.5 px-5", value: "Post testomonial" %>
  </div>
<% end %>

使用星形选择器向表单输入值编辑 jQuery - 工作

$(document).ready(function()
  /* 1. Visualizing things on Hover - See next part for action on click */
  $('#stars li').on('mouseover', function()
    var onStar = parseInt($(this).data('value'), 10); // The star currently mouse on

    // Now highlight all the stars that's not after the current hovered star
    $(this).parent().children('li.star').each(function(e)
      if (e < onStar) 
        $(this).addClass('hover');
      
      else 
        $(this).removeClass('hover');
      
    );

  ).on('mouseout', function()
    $(this).parent().children('li.star').each(function(e)
      $(this).removeClass('hover');
    );
  );
  /* 2. Action to perform on click */
  $('#stars li').on('click', function()
    var onStar = parseInt($(this).data('value'), 10); // The star currently selected
    var stars = $(this).parent().children('li.star');

    for (i = 0; i < stars.length; i++) 
      $(stars[i]).removeClass('selected');
    

    for (i = 0; i < onStar; i++) 
      $(stars[i]).addClass('selected');
    

    // JUST RESPONSE (Not needed)
    var ratingValue = parseInt($('#stars li.selected').last().data('value'), 10);
    $("#testomonial_star").val(ratingValue);
  );
);
function responseMessage(msg) 
  $('.success-box').fadeIn(200);
  $('.success-box div.text-message').html("<span>" + msg + "</span>");

【问题讨论】:

【参考方案1】:

当用户单击鼠标时,您可以将星值传递给输入 - rails 会在您的表单中为您的输入创建一个 id,我想在您的情况下将是 testomonial_star


/* 2. Action to perform on click */
  $('#stars li').on('click', function()
    ... same code here

    // JUST RESPONSE (Not needed)
    var ratingValue = parseInt($('#stars li.selected').last().data('value'), 10);
    //Add rating to the form
    $("#testomonial_star").val(ratingValue)

    ... same code here

  );

我会将星级输入设置为隐藏&lt;%= f.hidden_field :star %&gt;,因为您已经可以查看星级评分

【讨论】:

这非常有效,谢谢。我在问题中添加了修改后的表单和 jQuery。再次感谢

以上是关于使用 jQuery 星形选择器的 Rails 表单的主要内容,如果未能解决你的问题,请参考以下文章

Jquery选择器的分类

在提交失败时保持 jQuery - Rails

将jquery选择器的属性放入数组

jQuery:not选择器的说明和:checked选择器的使用

JQuery——表单对象属性筛选选择器和特殊选择器this

jQuery触发嵌套表单rails cocoon上的所有实例