2010-06-12 47 views
77

Es necesario disponer de varios botones de envío.¿Cómo creo varios botones de envío para el mismo formulario en Rails?

que tienen una forma que se crea una instancia de Contact_Call.

Un botón se crea como algo 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 lo hago? No puedo cambiar la ruta, ¿hay alguna manera de enviar una variable diferente que sea captada por [: params]?

Y si lo hago entonces, ¿qué hago en el controlador, configurar una declaración de caso?

+0

posible duplicado de [Rieles: botones de envío múltiple en un formulario] (http://stackoverflow.com/questions/3332449/rails-multi-submit-buttons-in-one-form) –

+2

Este es más antiguo y tiene mas votos En todo caso, lo anterior debe cerrarse como un duplicado de esto ... –

Respuesta

113

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 %> 

Esta es la salida:

<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 presentado 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, recuerda que esta fuertemente parejas su vista al controlador que puede no ser muy deseable.

+1

Ahora eso es algo nuevo. Gracias @Anurag! –

+1

así que simplemente poniendo la 'A' crea automáticamente el nombre del parámetro = 'confirmar'? – Angela

+0

¿Hay alguna manera como dijiste de no acoplar estrechamente la vista al controlador? por ejemplo, para que los botones de enviar cambien la URL? * Parece * que esto no es necesariamente malo porque un formulario envía variables que pueden cambiar el comportamiento del controlador, incluso si el usuario lo ingresa, ¿cuál es la selección del botón? – Angela

26

alternativa, puede reconocida que ha pulsado el botón de cambiar 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 hay que verificar la presencia teclas params en lugar de simplemente comprobar params[:commit] valor le enviará params[:a_button] o params[:b_button] dependiendo de lo que se ha pulsado.

+1

Aún no desacopla la vista desde el controlador. – slowpoison

+1

Sí, si el desacoplamiento significa evitar cierta lógica en la acción con el fin de encaminarlo a la acción final, tiene razón, todavía están acoplados.Solo quise decir que si usa el atributo de nombre en esa lógica, su controlador es independiente de lo que se muestra en el botón. Gracias, editado – masciugo

+4

Este parece ser mejor que el aceptado en situaciones i18n porque se muestra "valor" y si está mostrando caracteres Unicode se ensuciaría. –

8

Lo resolvimos usando advanced constraints en rieles.

La idea es tener la misma ruta (y, por lo tanto, la misma ruta con nombre & 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 verdadero si el PARAM cometer coincide con el attr caso dado. valor.

Esta disponible como una gema commit_param_matching.

11

solución similar a la sugerida por @ vss123 sin necesidad de utilizar ningún 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 

en cuenta que evito el uso de valor y el uso del nombre de entrada en lugar ya presento valor del botón es a menudo internacionalizado/traducido. Además, evitaría usar esto demasiado ya que desordenará rápidamente su archivo de rutas.

3

Una vieja pregunta, pero como 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 sólo vive en un solo lugar - como una constante en el controlador. Sin embargo, todavía no he intentado descubrir cómo hacerlo.

+0

¿Qué quieres decir con "i18n"? – skrrgwasme

+0

¿Era preferible utilizar restricciones en la ruta? ¡Gracias! – Angela

+0

@Scott: i18n significa 'internacionalización': básicamente, ¿cómo soportaría varios idiomas? Realmente no lo he investigado, así que no estoy muy familiarizado con cómo funciona ni cómo implementarlo. – Draknor

32

También hay otro enfoque, utilizando el atributo formAction en el botón de envío:

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

El código se mantiene limpio, como el estándar botón de creación no necesita ningún cambio, sólo se inserta una ruta de enrutamiento para el botón especial:

formAction:
el URI de un programa que procesa la información presentada por el elemento de entrada, si se trata de un botón o imagen enviar. Si se especifica, anula el atributo de acción del propietario del formulario del elemento. Fuente: MDN

+1

esto es compatible con todos los navegadores http://www.w3schools.com/tags/att_button_formaction.asp http://www.w3schools.com/tags/att_input_formaction.asp –

+3

Me doy cuenta de que la pregunta es antigua, pero aconsejo a los lectores que esta solución concisa merece una mejor consideración. – Jerome

+1

Desearía haber encontrado esta respuesta la primera vez que tuve esta misma pregunta. Estoy contento de haber decidido mirar un poco más profundo esta vez. Gran solución – rockusbacchus

1

que tiene un número variable de presentar botones de mi forma gracias a nested_form_fields, por lo que sólo utiliza el nombre no era suficiente para mí. Terminé incluyendo un campo de entrada oculto en el formulario y usando Javascript para completarlo cuando se presionó uno de los botones de envío de formulario.

Cuestiones relacionadas