Rails:一个表单中的多个提交按钮

Posted

技术标签:

【中文标题】Rails:一个表单中的多个提交按钮【英文标题】:Rails: Multi-submit buttons in one Form 【发布时间】:2011-03-20 22:24:58 【问题描述】:

假设我有一个文章模型,在文章的“新建”视图中,我有两个按钮,“发布”和“保存草稿”。

我的问题是如何知道在控制器中单击了哪个按钮。

我已经有了解决方案,但我认为一定有更好的方法。 我目前在视图中使用的是:

<div class="actions">
  <%= f.submit "Publish" %>
  <%= f.submit "Save Draft", :name => "commit" %>
</div>

所以在控制器中,我可以使用 params[:commit] 字符串来处理该操作。

def create
  @article = Article.new(params[:article])
  if params[:commit] == "Publish"
    @article.status = 'publish'
    // detail omitted
  end

  @article.save
end

但我认为使用视图相关的字符串并不好。你能告诉我另一种方法吗?

更新:由于这些按钮的形式相同,它们都将执行“创建”操作,这对我来说没问题。我想要的是在创建操作中处理它,例如给文章模型一个“状态”列并保存“公共”或“草稿”。

【问题讨论】:

How do I create multiple submit buttons for the same form in Rails? 的可能重复项 【参考方案1】:

也可以像这样在 form_for 助手上完成

 <%= f.submit "Publish",name: "publish", class: "tiny button radius success" %>
 <%= f.submit 'Mark as Draft', name: "draft", class: "tiny button radius " %>

和控制器上的逻辑是一样的

   if params[:publish]
      // your code
   elsif params[:draft]
      // your code
   end

【讨论】:

【参考方案2】:

Railscast episode 38 对此进行了介绍。使用params 哈希来检测哪个按钮被点击是正确的方法:

查看:

<%= submit_tag 'Create' %>
<%= submit_tag 'Create and Add Another', name: 'create_and_add' %>

控制器:

if params[:create_and_add]
  # Redirect to new form, for example.

else
  # Redirect to show the newly created record, for example.
end

【讨论】:

我已经看了一周的 Railscasts 剧集,但我确实错过了这一集。它似乎和我的代码一样,都使用参数哈希,但它做得更好,我也改进了我的代码。非常感谢! 如果您有一个在 newedit 操作中使用的 _form 部分,这将变得非常复杂。在这种情况下,您必须在 createupdate 操作中设置上述控制器逻辑,以解决用户创建新对象或编辑现有的。 @jayp 这是我现在正在尝试做的事情,希望您能在my question【参考方案3】:

通常我使用 John Topley 给出的建议(见上面的答案)。 另一种方法是使用 JQuery / JS 更改表单操作属性 - 单击提交按钮 示例:

form_tag( ,:method => 'post', :id => 'reports_action') do 
   .......
   ....... 
  submit_tag 'submit',  :onclick => "return changeAction();"
end

然后......

function changeAction()
   $('#reports_action').attr('action','my_new_action');
   

【讨论】:

【参考方案4】:

您还可以在提交按钮上设置一些data 属性,并使用javascript 更改单击其中一个按钮时的form 操作

【讨论】:

移动设备上的“点击”怎么样?【参考方案5】:

我们在 rails 中使用 advanced constraints 解决了问题。

这个想法是拥有相同的路径(因此具有相同的命名路由和动作),但具有路由到不同动作的约束。

resources :plan do
  post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
  post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end

CommitParamRouting 是一个简单的类,它有一个 matches? 方法,如果提交参数与给定的实例属性匹配,则返回 true。价值。

这可以作为 gem commit_param_matching.

【讨论】:

这太棒了。它解决了无法使用 POST 方法重定向的问题。【参考方案6】:

我记得曾经遇到过这个问题。您不能保留两个按钮,然后根据 params[:commit] 调用一些操作。提交按钮 onclick 将调用表单引用的 url。有一些不好的方法可以获得所需的行为。保留一个按钮来调用表单引用的动作并让另一个按钮调用动作,我使用了 link_to 然后更改样式以匹配按钮。此外,或者您可以使用 jQuery 更改表单将调用的 url,从而决定在运行时调用什么操作。希望这会有所帮助。

【讨论】:

对不起,我忘了提到我试图在同一个创建操作中处理这个问题,我已经更新了这个问题。但我也学习了你关于如何使用 jQuery 更改表单 url 的技巧,这很有帮助。谢谢。 this question 的唯一答案对我有用,它确实使用控制器中params[:commit] 的值来区分按下了哪个按钮。那就是当提交按钮在视图中定义为&lt;%= submit_tag( "X" ) %&gt;时的字符串“X”。

以上是关于Rails:一个表单中的多个提交按钮的主要内容,如果未能解决你的问题,请参考以下文章

php一个表单提交多个页面,怎样获取按钮提交过来的值

通过单击 Ruby on Rails 中的按钮生成表单

Rails 表单验证方式 + 无提交按钮

HTML 表单中的多个提交按钮

使用 js/jquery 在 ruby​​ on rails 中隐藏 form_tag 上的提交按钮

如何使用 Angular JS 处理表单中的多个提交按钮?