【问题标题】:how to submit form data without page reload in rails application如何在rails应用程序中提交表单数据而不重新加载页面
【发布时间】:2020-09-14 02:01:05
【问题描述】:

project_director 表有一个属性状态,它与project 具有 one_to_one 关联。
每次我的页面重新加载时,我都会在提交表单时使用 project_director 表单渲染项目。我从在线资源中尝试了 ajax,但我的页面仍然重新加载。这是我尝试过的。

index.html.erb

<%= form_for ProjectDirector.new do |f| %>
<td>
   <table class="approval-table">
      <tr>
         <td>
            <ul>
               <div>
                  <div class="wrapper-class">
                     <%= f.radio_button :status, true  %>
                     <%= f.label :approve %>
                     <br>
                     <%= f.radio_button :status, false  %>
                     <%= f.label :reject %>
                  </div>
                  <%=f.hidden_field :project_site_id, value: project_site.id%>
               </div>
            </ul>
         </td>
         <td>
            <%= f.hidden_field :user_id, value: current_user.id %>
            <%= f.submit 'Submit', :class => 'button primary small' %>
         </td>
      </tr>
   </table>
   <script>
      $(function(){
          $("#new_project_director").on("submit", function(event) {
              event.preventDefault();
      
              var formData = {
                  'status': $('input[name=project_director[status]]').val() //for get status
              };
              console.log(formData);
      
              $.ajax({
                  url: "/project_directors",
                  type: "post",
                  data: formData,
                  success: function(d) {
                      alert(d);
                  }
              });
          });
      })
      
   </script>
  </td>

project_directors_controller.rb

  def create
    @project_director =  ProjectDirector.new(remark_params)
      if @project_director.save
        redirect_to directors_index_path(anchor: 'panel2')
    end
  end
def remark_params
  params.require(:project_director).permit(:status, :projec_id, :user_id)
end

【问题讨论】:

  • 你看过Rails remote form handling吗?这可能会有所帮助。您可以在form_for 中设置remote=true(我认为)。这很奇怪,因为即使没有它,您的代码看起来也基本正确。我想知道重定向。如果create 端点确实为ajax 做好了准备,您可以只返回head :ok 而不是重定向。我想知道重定向是否正在接管?提交时是否看到 console.log 触发?
  • @mrrogers 添加了```remote: true```,在一次提交后,下一次提交仍然无法正常工作,直到我重新加载页面。
  • 一次提交后控制台出现此错误Error: Syntax error, unrecognized expression: input[name=project_director[status]
  • 嗯 - 这是很好的数据。第一次正确更新页面,对吗?然后第二个失败。我认为remote=true 你可能不需要你的提交处理程序。让我看看我是否可以模拟一个可能有帮助的答案。

标签: ruby-on-rails ajax


【解决方案1】:

Rails 在这里为您提供了很多帮助。我能够在没有大量额外的 javascript 并且没有深入研究实际表单字段的情况下完成这项工作,因为 Rails 已经知道这些东西是如何形成的以及如何 它应该一起工作。

注意:我有一个名为 Thing 的模型,它有一个 accepted 布尔属性。这应该对应于您的ProjectDirector(大致)。

在表格中

<%= form_for(thing, remote: true) do |f| %>
  <%= f.check_box :accepted %>
  <%= f.submit 'Submit', :class => 'button primary small' %>
<% end %>

在控制器中

# things_controller.rb
  def create
    @thing = Thing.new(thing_params)


    if @thing.save
      if request.xhr?
        render json: { success: true }
      else
        redirect_to @thing, notice: "Thing was successfully created."
      end
    else
      render :new
    end
  end

如果我创建一个新的Thing,页面不会刷新,它会采用我的布尔值。

您会注意到没有真正的附加 javascript。 Rails UJS 只需在表单中添加 remote: true 即可为我处理。

这不会处理您尝试执行的可能重定向,即在网站上加载新标签。要在成功提交后触发操作, 您可以使用类似的方法添加成功和失败的侦听器

 $('#my-form-id').on('ajax:success', function(event){
    const [data, status, xhr] = event.detail
    alert(xhr.responseText)
    // or 
    alert(data.success)
 }).on('ajax:error',function(event){
    alert("Something went wrong")
 });

查看this stackoverflow post 或 阅读 Ruby on Rails 指南here

【讨论】:

  • 数据现在可以正确传递,无需重新加载页面,但没有向用户显示成功或错误消息
  • 此时,rails flash 并不适合您。它指望页面重新加载。所以你必须在ajax:success 监听器中处理它。您当然可以更新控制器的响应以返回成功消息,例如render json: { success: "Way to go"},然后在前端您需要使用 javascript 将其放在页面上。
  • 我第一次添加 ajax,你能告诉我如何用 javascript 放在页面上吗?
  • 我更新了解决方案以及您的 ajax:success 事件侦听器的外观。
  • 我添加了 turbo 链接,但仍然会发出警报响应,我只在第一次提交时看到,而不是 2,3.. 提交时无需重新加载页面
猜你喜欢
  • 1970-01-01
  • 2016-03-28
  • 2017-08-18
  • 2021-11-12
  • 1970-01-01
相关资源
最近更新 更多