¿Cómo puedo crear varios botones de envío para el mismo formulario en Rails?


Necesito tener varios botones de envío.

Tengo un formulario que crea una instancia de Contact_Call.

Un botón lo crea como normal.

El otro botón lo crea, pero necesita tener un valor de atributo diferente del predeterminado, y también necesita establecer el atributo en un modelo diferente, pero relacionado, utilizado en el controlador.

¿Cómo hago eso? No puedo cambiar la ruta, por lo que hay una manera de enviar una variable diferente que se recoge por [:params]?

Y si lo hago entonces, ¿qué hago en el controlador, configurar una sentencia case?

Author: the Tin Man, 2010-06-12

7 answers

Puede crear varios botones de envío y proporcionar un valor diferente a cada uno:

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

Esto producirá:

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

Dentro de su controlador, el valor del botón enviado será identificado por el parámetro commit. Compruebe el valor para hacer el procesamiento requerido:

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

Sin embargo, recuerde que esto combina estrechamente su punto de vista con el controlador que puede no ser muy deseable.

 119
Author: Anurag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-12 02:23:40

También hay otro enfoque, usando el atributo formaction en el botón submit:

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

El código permanece limpio, ya que el botón crear estándar no necesita ningún cambio, solo inserta una ruta de enrutamiento para el botón especial:

Formacción:
URI de un programa que procesa la información enviada por el elemento input, si se trata de un botón submit o imagen. Si se especifica, reemplaza el atributo action del propietario del formulario del elemento. Fuente: MDN

 47
Author: patpir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-12 08:49:05

Alternativamente puede reconocer qué botón se presionó cambiando su nombre de atributo.

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

Es un poco incómodo porque tienes que comprobar la presencia de las teclas params en lugar de simplemente comprobar el valor params[:commit]: recibirás params[:a_button] o params[:b_button] dependiendo de cuál se presionó.

 28
Author: masciugo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-18 14:54:55

Solución similar a una sugerida por @vss123 sin usar gemas:

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

Observe que evito usar value y uso input name en su lugar, ya que el valor del botón submit a menudo se internacionaliza / traduce. Además, evitaría usar esto demasiado, ya que desordenará rápidamente su archivo de rutas.

 12
Author: Tadas Sasnauskas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-30 11:51:40

Resolvimos usando advanced constraints en rails.

La idea es tener la misma ruta (y por lo tanto la misma ruta y acción) pero con restricciones de enrutamiento a diferentes acciones.

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

CommitParamRouting es una clase simple que tiene un método matches? que devuelve true si el parámetro de confirmación coincide con la instancia attr dada. valor.

Esto está disponible como una gema commit_param_matching.

 9
Author: siliconsenthil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-27 18:33:09

Una vieja pregunta, pero ya que he estado lidiando con la misma situación, pensé en publicar mi solución. Estoy usando constantes de controlador para evitar introducir una discrepancia entre la lógica del controlador y el botón de vista.

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

Y luego en la vista:

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

De esta manera el texto solo vive en un lugar - como una constante en el controlador. No he tratado de averiguar cómo i18n esto todavía, sin embargo.

 3
Author: Draknor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-24 22:27:24

Tengo un número variable de botones de envío en mi formulario gracias a nested_form_fields, así que usar el nombre no fue suficiente para mí. Terminé incluyendo un campo de entrada oculto en el formulario y usando Javascript para rellenarlo cuando se presionó uno de los botones de envío del formulario.

 1
Author: Shawn Walton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-19 19:48:53