使用 JavaScript 提交 Rails 远程表单

发布于 2024-12-22 04:28:34 字数 525 浏览 1 评论 0原文

在我的 Rails 应用程序中,我有一个远程表单,看起来像这样:

<%= form_tag some_path, :method => :get, :id => 'my-form', :remote => true do %>
  <%= text_field_tag :search, params[:search], :id => 'search-field' %>
  <%= submit_tag 'Go' %>
<% end %>

现在我想通过 javascript 提交此表单并触发所有 Rails 远程表单回调。到目前为止,我已经尝试了一些方法,但似乎没有任何效果。

我尝试过的事情:

$('#my-form').trigger('onsubmit')

$.rails.callFormSubmitBindings( $('#search-form') )

但到目前为止还没有运气。有什么想法吗?

In my rails app I have a remote form that looks something like this for example:

<%= form_tag some_path, :method => :get, :id => 'my-form', :remote => true do %>
  <%= text_field_tag :search, params[:search], :id => 'search-field' %>
  <%= submit_tag 'Go' %>
<% end %>

Now i would like to submit this form via javascript and trigger all rails remote form callbacks. So far i have tried a few things but nothing seems to be working.

Things i have tried:

$('#my-form').trigger('onsubmit')

$.rails.callFormSubmitBindings( $('#search-form') )

but no luck so far. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

a√萤火虫的光℡ 2024-12-29 04:28:34

在 Rails 5.1+ 中,用非 jquery rails-ujs 替换了旧的 jquery-ujs ,上述答案不再有效,始终通过 HTML HTTP 提交表单要求。这就是触发新的 Rails 提交事件处理程序的方式:(

var elem = document.getElementById('myform') // or $('#myform')[0] with jQuery
Rails.fire(elem, 'submit');

无法告诉你我花了多长时间才弄清楚这个问题...)出于某种原因,常规事件不会正确地冒泡到委托的事件处理程序附加Rails 使用rails的新委托函数,当它们由 jQuery 触发时。

In Rails 5.1+, which replaces the old jquery-ujs with a non-jquery rails-ujs, the above answers no longer work, always submitting the form via an HTML HTTP request. This is how you trigger the new rails submit event handler:

var elem = document.getElementById('myform') // or $('#myform')[0] with jQuery
Rails.fire(elem, 'submit');

(Can't tell you how long it took me to figure that one out...) For some reason, the regular events don't bubble up properly to the delegated event handler attached by rails using rails' new delegate function, when they are triggered by jQuery.

我爱人 2024-12-29 04:28:34

这只是 Rails 的方式:

 $("#myform").trigger('submit.rails');

This is simply in Rails way :

 $("#myform").trigger('submit.rails');
彼岸花似海 2024-12-29 04:28:34

使用 rails_ujs 并简单地执行以下操作怎么样:(

Rails.fire(form, 'submit');

其中 form 是一个 DOM 元素)

这感觉像是正确的 Rails 方法。

您可以在此处查看源代码 - https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/utils/event.coffee#L34

How about using rails_ujs and simply do the following:

Rails.fire(form, 'submit');

(where form is a DOM Element)

This feels like a proper Rails way to do it.

You can check out the source here – https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/utils/event.coffee#L34

澉约 2024-12-29 04:28:34

如果您无法通过 javascript 访问 Rails,并且您不想尝试进行设置,那么有一个更简单的解决方案!

您可以在 html 元素上使用 requestSubmit 而不是 Submit,它会按照您期望的方式工作,因为 requestSubmit 会引发 submit 甚至,而 submit 则不然。

在这里查看提交和请求提交之间的区别:
https://developer.mozilla.org/en-US/docs /Web/API/HTMLFormElement/submit

在上面的情况下,您可以使用:

$('#my-form')[0].requestSubmit()

If you don't have access to Rails from your javascript, and you don't want to try to get it set up, there is an easier solution!

You can use requestSubmit on the html element, instead of submit, and it will work the way you'd expect it to, since requestSubmit raises a submit even, and submit does not.

See the difference between submit and requestSubmit here:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit

In the case above, you could use:

$('#my-form')[0].requestSubmit()
李白 2024-12-29 04:28:34

从控制器传递 json 并通过 js 捕获它怎么样?

现在,控制器的操作为

respond_to do |format|
      if some condition
        format.json { render :json => {:success => true} }
        format.html{ redirect_to some_path, :notice => "successfully created" }
      else
        ...
      end
end

并在 js 中捕获 json 为

$('#my-form').bind 'ajax:success', (event,data) ->
  if(data.success == true)
    ...

不完全是您正在寻找的内容,但希望这对您有所帮助。

How about passing json from controller and capturing it by your js.

Now, controller's action as

respond_to do |format|
      if some condition
        format.json { render :json => {:success => true} }
        format.html{ redirect_to some_path, :notice => "successfully created" }
      else
        ...
      end
end

And capturing the json in js as

$('#my-form').bind 'ajax:success', (event,data) ->
  if(data.success == true)
    ...

Not exactly what you are looking for but hope this turns out to be of any help.

柠檬色的秋千 2024-12-29 04:28:34

我正在更新 Rails 6 的答案。

如果您在 Rails 6 中遇到此问题,很可能您忘记将参数“format: :js”添加到表单生成器。

<%= form_tag some_path, :method => :get, :id => 'my-form', :remote => true,
         :format => :js do %>
  <%= text_field_tag :search, params[:search], :id => 'search-field' %>
  <%= submit_tag 'Go' %>
<% end %>

您还需要在控制器中包含 format.js。

def update
    respond_to do |format|
      if @model.update(user_params)
        format.html { redirect_to @model, notice: 'Model was successfully updated.' }
        format.json { render :show, status: :ok, location: @model }
        format.js {
          logger.debug "this will run in the update was ok."
        }
      else
        format.html { render :edit }
        format.json { render json: @model.errors, status: :unprocessable_entity }
        format.js {
          logger.debug "this will run in the update was not ok."
        }
      end
    end
  end

现在,您可以通过 JavaScript 定期调用此表单的提交。

this.form.submit()

I'm updatting the answer to rails 6.

If you are having this issue in rails 6, it is likelly that you forgot to add the parameter "format: :js" to the form builder.

<%= form_tag some_path, :method => :get, :id => 'my-form', :remote => true,
         :format => :js do %>
  <%= text_field_tag :search, params[:search], :id => 'search-field' %>
  <%= submit_tag 'Go' %>
<% end %>

You will also need to include a format.js in your controller.

def update
    respond_to do |format|
      if @model.update(user_params)
        format.html { redirect_to @model, notice: 'Model was successfully updated.' }
        format.json { render :show, status: :ok, location: @model }
        format.js {
          logger.debug "this will run in the update was ok."
        }
      else
        format.html { render :edit }
        format.json { render json: @model.errors, status: :unprocessable_entity }
        format.js {
          logger.debug "this will run in the update was not ok."
        }
      end
    end
  end

Now, from the JavaScript, you can just call the submit to this form regularly.

this.form.submit()
晨敛清荷 2024-12-29 04:28:34

我知道这是一个老话题,但我已经为此苦苦挣扎了一段时间,终于找到了解决方案。

我有一个带有 remote: true 的表单,其中包含 file_field,我希望表单在用户添加文件后立即自动提交。我尝试了 onchange: form.submit(); 但这样表单是以 HTML 形式提交的。

我的解决方案:使用 JS 单击(隐藏)表单提交按钮:

onchange: $("#submit-button").click();

I know this is an old topic but I have been struggling with this now for some time and finally found a solution.

I had a form with remote: true that included a file_field and I wanted the form to submit automatically as soon as the user added the file. I tried onchange: form.submit(); but that way the form was submitted as HTML.

My solution: clicking the (hidden) form submit button with JS:

onchange: $("#submit-button").click();
无人问我粥可暖 2024-12-29 04:28:34

@mltsy 答案非常适合我。不过,想重申一下,这需要使用rails-ujs。如果你像我一样从旧版本升级,你可能仍在使用jquery依赖的jquery_ujs。如果您在控制台中收到 ReferenceError: Can't find variable: Rails ,请检查您的 application.js 并确保您有rails-ujs,否则 @mltsy 的精彩答案将不起作用。我想留下评论而不是答案,但 Stack 不允许我这样做。

@mltsy answer works perfect for me. However, wanted to reiterate that this requires the use of rails-ujs. If you've upgraded from an older version like me, you might still be using the jquery dependent jquery_ujs. If you're getting ReferenceError: Can't find variable: Rails in your console, check your application.js and make sure you have rails-ujs or @mltsy's great answer won't work. I wanted to leave a comment instead of an answer, but Stack won't let me.

莫言歌 2024-12-29 04:28:34

你可以只使用 .submit();

$("#my-form").submit();

You can just use .submit();

$("#my-form").submit();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文