2010-06-12 62 views
77

我需要有多个提交按钮。如何在Rails中为同一表单创建多个提交按钮?

我有一个窗体,它创建一个Contact_Call的实例。

一个按钮会像平常一样创建它。

其他按钮创建它,但需要具有与默认值不同的属性值,并且还需要在控制器中使用的不同但相关的模型上设置属性。

我该怎么做?我不能改变路线,那么有没有办法发送一个不同的变量,它会被[:params]拾取?

如果我那么做,我该怎么做控制器,建立一个案例陈述?

+0

可能重复的[Rails:多个提交按钮在一个表单中](http://stackoverflow.com/questions/3332449/rails-multi-submit-buttons-in-one-form) – 2015-06-22 18:23:22

+2

这个是旧的和有更多的选票。如果有什么上述应该被关闭作为这个副本... – 2015-06-23 04:32:22

回答

113

您可以创建多个提交按钮,并提供不同的值给每个:

<% form_for(something) do |f| %> 
    .. 
    <%= f.submit 'A' %> 
    <%= f.submit 'B' %> 
    .. 
<% end %> 

这将输出:

<input type="submit" value="A" id=".." name="commit" /> 
<input type="submit" value="B" id=".." name="commit" /> 

内部控制器,提交按钮的值将由参数标识commit。检查值做必要的处理:

def <controller action> 
    if params[:commit] == 'A' 
     # A was pressed 
    elsif params[:commit] == 'B' 
     # B was pressed 
    end 
end 

但是,请记住,这个紧密结合您的视图控制器可能不是非常理想。

+1

现在这是一些新的东西。谢谢@Anurag! – 2010-06-12 02:38:54

+1

所以只需将'A'自动创建参数名称='提交'? – Angela 2010-06-12 06:00:02

+0

有没有办法像你所说的那样将视图紧密地连接到控制器?例如,用于提交按钮来更改URL?它似乎*这不一定是不好的,因为表单提交可以改变控制器行为的变量,如果它是用户输入的,哪个按钮的选择是? – Angela 2010-06-12 06:07:27

26

您可以选择识别更改其属性名称的按钮。

<% form_for(something) do |f| %> 
    .. 
    <%= f.submit 'A', name: 'a_button' %> 
    <%= f.submit 'B', name: 'b_button' %> 
    .. 
<% end %> 

这是一个有点有点不舒服,因为你必须检查PARAMS键的存在,而不是简单地检查params[:commit]值:您会收到params[:a_button]params[:b_button]取决于按下其中一个上。

+1

仍然不会从控制器中分离视图。 – slowpoison 2013-05-26 08:39:49

+1

是的,如果分离意味着在行动中避免某些逻辑以便路由到最后的行动,那么它们仍然是耦合的。我的意思是说,如果你在该逻辑中使用name属性,那么你的控制器是独立于按钮上显示的。谢谢,编辑 – masciugo 2013-05-29 08:36:50

+4

这一个似乎比在i18n情况下接受的更好,因为“值”显示,如果你显示Unicode字符,它会变得混乱。 – 2015-03-04 06:11:03

8

我们在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?如果提交PARAM给定的情况下ATTR匹配返回true。值。

这是一个宝石commit_param_matching

11

类似的解决方案,以一个不使用任何宝石由@ vss123建议:

resources :plan do 
    post :save, constraints: lambda {|req| req.params.key?(:propose)}, action: :propose 
    post :save, constraints: lambda {|req| req.params.key?(:finalize)}, action: :finalize 
end 

请注意,我避免使用的价值和使用输入名称,而不是因为提交按钮值往往是国际化/翻译。另外,我会避免使用这个太多,因为它会很快混乱你的路线文件。

3

一个古老的问题,但由于我一直在处理相同的情况,我想我会发布我的解决方案。我使用控制器常量来避免引入控制器逻辑和视图按钮之间的差异。

class SearchController < ApplicationController 
    SEARCH_TYPES = { 
    :searchABC => "Search ABCs", 
    :search123 => "Search 123s" 
    } 

    def search 
    [...] 
    if params[:commit] == SEARCH_TYPES[:searchABC] 
     [...] 
    elsif params[:commit] == SEARCH_TYPES[:search123] 
     [...] 
    else 
     flash[:error] = "Search type not found!"] 
     [...] 
    end 
    end 
    [...]   
end 

然后在视图:

<% form_for(something) do |f| %> 
    [...] 
    <%= f.submit SearchController::SEARCH_TYPES[:searchABC] %> 
    <%= f.submit SearchController::SEARCH_TYPES[:search123] %> 
    [...] 
<% end %> 

这样的文字只住在一个地方 - 在控制器中的常数。然而,我还没有试图找出如何解决这个问题。

+0

“i18n”是什么意思? – skrrgwasme 2014-07-24 22:55:21

+0

这是比在路线中使用约束更好吗?谢谢! – Angela 2014-07-26 00:44:54

+0

@Scott:i18n意味着'国际化' - 基本上,你会如何支持多种语言。我没有真正关注过它,所以我不太了解它的工作原理或如何实现它。 – Draknor 2014-08-14 15:44:32

32

也有另一种方法,使用formaction属性提交按钮:

<% form_for(something) do |f| %> 
    ... 
    <%= f.submit "Create" %> 
    <%= f.submit "Special Action", formaction: special_action_path %> 
<% end %> 

代码保持清洁,如标准的创建按钮,不需要任何改变,你只插入一个路由路径特殊按钮:

formaction:
,其处理提交的输入元件中的信息,如果它是一个提交按钮或图像的程序的URI。如果指定,则其将覆盖该元素的表单所有者的操作属性。 来源:MDN

+1

这是所有浏览器支持http://www.w3schools.com/tags/att_button_formaction.asp http://www.w3schools.com/tags/att_input_formaction.asp – 2016-05-13 18:02:51

+3

我意识到这个问题是旧的,但我建议读者这个简洁的解决方案值得更好的考虑。 – Jerome 2016-11-12 09:22:29

+1

我希望在第一次有同样的问题时我找到了这个答案。我很高兴这次我决定再深入一点。好的解决方案 – rockusbacchus 2017-08-23 21:44:28

1

我有我的形式感谢nested_form_fields上可变数量提交按钮,所以只是用名字是不够的我。我最终在表单中包含一个隐藏的输入字段,并在按下表单提交按钮之一时使用Javascript填充它。

相关问题