Considere cambiar la respuesta aceptada a la respuesta de Parrots .
Peter Mortensen
2
@PeterMortensen - Ni la respuesta aceptada ni la respuesta de Parrot son las mejores hoy. Vea la respuesta de Leo para la nueva solución HTML5 usando el atributo formaction. O vea la respuesta de kiril sobre cómo hacer que el HTML sea visible para el usuario sea independiente del valor enviado al navegador, resolviendo el problema de internacionalización de una manera más fácil de codificar que la respuesta de Greg o Parrot.
ToolmakerSteve
Respuestas:
448
Si le da un nombre a cada uno, el clic será enviado como cualquier otra entrada.
¡También asegúrese de que el nombre del botón tenga el nombre correcto! Por ejemplo, "botón-1" NO funcionaría. Puede ahorrarle problemas a alguien, así que tenga esto en cuenta.
pdolinaj
22
Normalmente, todas las entradas en el formulario se envían con el formulario. Dado que el valor de un botón se envía solo si se hace clic, tendría que buscar en los valores del formulario estos nombres predefinidos. Creo que la otra respuesta ( stackoverflow.com/a/21778226/88409 ) que implica darles a todos el mismo nombre, con valores diferentes, tiene más sentido. Luego simplemente toma el valor bajo un solo nombre de campo de formulario conocido. También hace que sea más obvio que solo se enviará un valor (el clic) para el nombre de entrada dado, de forma muy similar a cómo funcionan los botones de opción (mismo nombre, valores diferentes).
Triynko
66
@Triynko, como Robin Green dijo en los comentarios de esa respuesta, esta es mejor para la internacionalización. Por ejemplo, si la página se representa en español, el texto de los botones probablemente será diferente. Entonces, tener la lógica de su código depende del texto de ese botón se romperá en ese caso. Ir por el nombre es más seguro, ya que es un valor que no se muestra al usuario y, por lo tanto, puede tratarse más como una variable "privada" y menos como un mensaje para los usuarios.
sfarbota
Para aclarar el comentario de @ sfarbota: La primera solución que se muestra en la respuesta de Parrot es problemática, ya que se basa en probar el valor visible para el usuario . Eso es dudoso: el código que se rompe al cambiar una palabra visible para el usuario se considera "frágil". La segunda solución que se muestra en la respuesta de Parrot está bien, es la misma que esta. La segunda solución de Parrot también muestra el código correspondiente para escribir, por lo tanto, es una respuesta más útil que esta.
ToolmakerSteve
2
Vea la respuesta de Leo para la nueva solución HTML5 usando el atributo formaction. O vea la respuesta de kiril sobre cómo hacer que el HTML sea visible para el usuario sea independiente del valor enviado al navegador, resolviendo el problema de internacionalización.
ToolmakerSteve
875
Solución 1:
asigne a cada entrada un valor diferente y mantenga el mismo nombre:
Para fines de 1818 podría ser mejor usar la respuesta seleccionada.
Robin Green
11
@LaszloPapp como dice la respuesta, si usa la respuesta seleccionada arriba, puede internacionalizar el formulario (es decir, traducirlo a diferentes idiomas o dialectos) sin afectar la lógica. Si utiliza la primera opción en esta respuesta, la lógica depende del idioma en el que se presenta el formulario.
Robin Green
1
@RobinGreen: Creo que la mayoría de la gente usará la segunda lógica, ¿no?
lpapp
55
i18n = i [nternationalizatio] n, y el 18 representa las 18 letras entre la primera y la última.
Buttle Butkus
18
El OP no solicitó PHP.
Rudey
110
Una solución aún mejor consiste en usar etiquetas de botón para enviar el formulario:
El HTML dentro del botón (por ejemplo, ..>Update<..es lo que ve el usuario; porque se proporciona HTML, valueno es visible para el usuario; solo se envía al servidor. De esta manera no hay inconveniente con la internacionalización y los múltiples idiomas de visualización (en el antigua solución, la etiqueta del botón también es el valor enviado al servidor).
Aparentemente, el comportamiento del navegador difiere; algunos envían el atributo de valor, otros la cadena entre las etiquetas ... Así que tenga cuidado con este.
@kiril el fragmento de ese enlace utiliza dos tipos diferentes de <button>: submity reset. Tenga en cuenta que resetno envía nada, solo restablece el formulario. Entonces el argumento de Jeroen permanece.
fizruk
77
Ok, tienes razón. Luego, revisé el Borrador de Trabajo HTML5 W3C. Cita: >> El atributo de valor proporciona el valor del elemento a los efectos del envío del formulario. El valor del elemento es el valor del atributo de valor del elemento, si hay uno, o la cadena vacía de lo contrario. >> NOTA: Un botón (y su valor) solo se incluye en el envío del formulario si el botón mismo se usó para iniciar el envío del formulario.
Kiril
8
@Jeroen Bull. ¿Qué navegadores envían el texto entre las etiquetas? Una entrada o botón solo debe enviar el atributo 'valor'. Un botón podría tener literalmente cualquier cosa entre sus etiquetas, incluidas imágenes u otras etiquetas HTML. Ese es el objetivo de usar un botón sobre un elemento de entrada, y ¿estás tratando de sugerir que el navegador va a volcar todo ese contenido como valor? De ninguna manera.
Triynko
93
Hay un nuevo enfoque HTML5 para esto, el formactionatributo:
Personalmente, generalmente uso Javascript para enviar formularios de forma remota (para una retroalimentación percibida más rápida) con este enfoque como copia de seguridad. Entre los dos, las únicas personas que no están cubiertas son IE <9 con Javascript deshabilitado.
Por supuesto, esto puede ser inapropiado si básicamente está tomando la misma acción del lado del servidor, independientemente de qué botón se haya presionado, pero a menudo si hay dos acciones del lado del usuario disponibles, también se asignarán a dos acciones del lado del servidor.
Editar:
como señaló Pascal_dher en los comentarios, este atributo también está disponible en la <input>etiqueta.
También disponible para la etiqueta "input". De acuerdo con w3schools: cuando se usa la etiqueta de botón, diferentes navegadores pueden enviar diferentes valores: w3schools.com/tags/tag_button.asp
Pascal_dher
3
He sido desarrollador web durante 12 años y este es nuevo para mí y en realidad era exactamente lo que necesitaba. ¡Gracias!
KyleFarris
1
De nada @KyleFarris! Creo que esto solo ha sido posible hace relativamente poco tiempo, por lo que no es de extrañar que aún no lo hayas encontrado.
Leo
2
Nota para los usuarios de Rails: agregar este atributo no funcionará si su formulario se crea usando form_tag. La única forma de hacerlo funcionar es cambiar form_fory usar f.submit formaction: 'your_path'.
Usar GET aquí es una práctica algo mala, uno debería usar POST cuando sea posible.
Syncrossus
66
@Syncrossus Eso es para fines de prueba.
Etienne Martin
22
Use el formactionatributo HTML (5ª línea):
<formaction="/action_page.php"method="get">
First name: <inputtype="text"name="fname"><br>
Last name: <inputtype="text"name="lname"><br><buttontype="submit">Submit</button><br><buttontype="submit"formaction="/action_page2.php">Submit to another page</button></form>
Característica HTML5. Funciona perfectamente en navegadores web recientes, ¡gracias!
Stephane Lallemagne
1
NOTA: Esto parece ser lo mismo que la respuesta anterior de Leo , excepto que muestra el uso de la inputetiqueta en lugar de la buttonetiqueta.
ToolmakerSteve
11
La mejor manera de lidiar con el botón de envío múltiple es mediante el uso de mayúsculas y minúsculas en la secuencia de comandos del servidor
<formaction="demo_form.php"method="get">
Choose your favorite subject:
<buttonname="subject"type="submit"value="html">HTML</button><buttonname="subject"type="submit"value="css">CSS</button><buttonname="subject"type="submit"value="javascript">Java Script</button><buttonname="subject"type="submit"value="jquery">jQuery</button></form>
código del servidor / secuencia de comandos del servidor - donde está enviando el formulario:
demo_form.php
<?php
switch($_REQUEST['subject']){case'html'://action for html herebreak;case'css'://action for css herebreak;case'javascript'://action for javascript herebreak;case'jquery'://action for jquery herebreak;}?>
Sí, debe tener una idea sobre los scripts de acción (tecnología de scripts del lado del servidor). Puede usar cualquier script / archivo para procesar los datos enviados, por ejemplo, php, asp, jsp, etc. <form action="demo_form.php" method="get">
Shailesh Sonare
Bueno. Esto fue confuso porque también hay un lenguaje llamado ActionScript. Debería decir: "código de servidor" o "script de servidor" en su lugar.
Civil
No tenía idea de que podías hacer eso con botones
William Isted
10
Quizás las soluciones sugeridas aquí funcionaron en 2009, pero he probado todas estas respuestas votadas y nadie está trabajando en ningún navegador.
La única solución que encontré que funciona es esta: (pero creo que es un poco feo de usar)
¿Por qué no solo usar formaction="actionurl1"? No necesitas JavaScript.
rybo111
3
@ rybo111 IE9 browser (la bruja es relativamente utilizada todavía) no es compatibleformaction
clueless007
1
@inaliaghle Es cierto, es aproximadamente el 1% de los usuarios, depende de a quién va dirigido el proyecto. Aproximadamente el 1% de los usuarios no usan JavaScript.
rybo111
1
Para futuros lectores: no hay nada de malo en usar JavaScript, como en esta respuesta. Es una habilidad útil para saber. OTOH, las respuestas más votadas también funcionan bien: ignore la oración principal de esta respuesta. Si por alguna razón no puede hacer que esas otras respuestas funcionen, publique su código completo como una pregunta SO, explique qué sucede (o no sucede) y pregunte qué está haciendo mal.
ToolmakerSteve
6
Definir namecomo array.
<formaction=''method=POST>
(...) some input fields (...)
<inputtype=submitname=submit[save]value=Save><inputtype=submitname=submit[delete]value=Delete></form>
Ejemplo de código de servidor (PHP):
if(isset($_POST["submit"])){
$sub = $_POST["submit"];if(isset($sub["save"])){// save something;} elseif (isset($sub["delete"])){// delete something}}
elseifmuy importante, porque ambos se analizarán si no. Disfrutar.
Ahora, esta es una excelente sugerencia, principalmente porque puede agregar más botones con más casos muy fácilmente, y usar un switchcon una acción predeterminada si uno ha agregado un botón y se olvidó de agregarlo a switch(y / o escribir mal algo, etc.)
Gwyneth Llewelyn
Además, @Pato agregó una respuesta similar que posiblemente sea más idiomática, ¡pero la tuya funciona bien!
Gwyneth Llewelyn
1
@GwynethLlewelyn No vi la otra respuesta o no me di cuenta cuando escribí la mía. En realidad es lo mismo, pero esto simplemente enfatiza cómo la mayoría de la gente prefiere esta lógica. La diferencia es solo con los nombres por razones semánticas, una buena comprensión para los novatos o para quienes les gusta comenzar con ellos.
Thielicious
5
Como no especificó qué método de script del lado del servidor está utilizando, le daré un ejemplo que funciona para Python, usando CherryPy (aunque también puede ser útil para otros contextos):
<buttontype="submit"name="register">Create a new account</button><buttontype="submit"name="login">Log into your account</button>
En lugar de usar el valor para determinar qué botón se presionó, puede usar el nombre (con la <button>etiqueta en lugar de <input>). De esa forma, si sus botones tienen el mismo texto, no causará problemas. Los nombres de todos los elementos del formulario, incluidos los botones, se envían como parte de la URL. En CherryPy, cada uno de ellos es un argumento para un método que hace el código del lado del servidor. Entonces, si su método solo tiene **kwargssu lista de parámetros (en lugar de escribir tediosamente cada nombre de cada elemento del formulario), puede verificar qué botón se presionó de esta manera:
if"register"in kwargs:pass#Do the register codeelif"login"in kwargs:pass#Do the login code
<formmethod="post"><inputtype="hidden"name="id"value="'.$id.'"readonly="readonly"/>'; //any value to post PHP
<inputtype='submit'name='update'value='update'formAction='updateCars.php'/><inputtype='submit'name='delete'value='delete'formAction='sqlDelete.php'/></form>
Un caso de uso común sería usar diferentes identificadores de una base de datos para cada botón, para que luego pueda saber en el servidor en qué fila se hizo clic.
En el lado del servidor (PHP en este ejemplo) puede leer "fila" como una matriz para obtener la identificación.
$_POST['row']será una matriz con solo un elemento, en la forma [ id => value ](por ejemplo:) [ '123' => 'something' ].
Entonces, para obtener la identificación clicada, debes:
Esto es similar a la respuesta publicada por @Thielicious , pero la suya es posiblemente más idiomática. Personalmente, prefiero usar etiquetas alfanuméricas para el índice (en lugar de números) para facilitar la lectura (es más fácil recordar lo que se supone que debe hacer cada botón), pero YMMV. ¡Pero aprovechar $_POST['row']ser una matriz asociativa es inteligente!
Gwyneth Llewelyn
1
Estoy de acuerdo en que, si se trata de botones estáticos, debe usar teclas con nombre. Pero en algunos casos no puedes. A veces genera esas entradas dinámicamente. El caso más común de esto sería una lista de filas, cada una identificada por una identificación. Creo que estaba pensando en ese caso cuando escribí la respuesta (¡hace 4 años!). Lo he editado, por lo que es más obvio que el número es una identificación y no un índice.
Pato
¡Bien hecho! Sí, estoy de acuerdo, es más obvio ahora; Todavía creo que su respuesta es marginalmente mejor que la de @Thielicious (y posiblemente incluso un poco más eficiente, especialmente si hay muchos botones).
Gwyneth Llewelyn
1
Tu formación para botón de envío múltiple en un ejemplo de formulario
Esto no funcionaría para controladores bajo POSTrutas.
Xavi Montero
por lo tanto, "envíe un mensaje"
Jonathan Laliberte
3
Lamento no estar de acuerdo, pero GETno siempre es adecuado. Si "modifica el estado de su modelo" , nunca debería usar a GET, ya que la actualización del navegador podría generar el envío transparente de dos veces la misma solicitud. Úselo GETsolo para "ver" cosas y POSTenviar solicitudes de cambios de estado (agregar, eliminar, editar, etc.). luego, en la POSTacción del controlador, altere el estado (base de datos, sesion ...) y emita una respuesta de redireccionamiento que luego sea GETel nuevo estado alterado. Hacer la GETalteración del estado del modelo es muy sucio y cualquier buen codificador debería evitarlo. Lamento decir eso. Código limpio rulez.
Xavi Montero
Cierto. Pero jugar sucio a veces puede ser limpio. Depende de lo que estés haciendo exactamente. Personalmente, no mapearía las solicitudes de eliminación y edición en un get, pero hay formas de hacerlo funcionar ... como verificar si ya se ha eliminado, o verificar si el usuario tiene permiso para hacerlo, etc ...
Como no especificó qué método de script del lado del servidor está utilizando, le daré un ejemplo que funciona para PHP
<?php
if(isset($_POST["loginForm"])){
print_r ($_POST);// FOR Showing POST DATA}
elseif(isset($_POST["registrationForm"])){
print_r ($_POST);}
elseif(isset($_POST["saveForm"])){
print_r ($_POST);}else{}?><html><head></head><body><fieldset><legend>FORM-1 with 2 buttons</legend><formmethod="post"><inputtype="text"name="loginname"value="ABC"><!--Always use type="password" for password --><inputtype="text"name="loginpassword"value="abc123"><inputtype="submit"name="loginForm"value="Login"><!--SUBMIT Button 1 --><inputtype="submit"name="saveForm"value="Save"><!--SUBMIT Button 2 --></form></fieldset><fieldset><legend>FORM-2 with 1 button</legend><formmethod="post"><inputtype="text"name="registrationname"value="XYZ"><!--Always use type="password" for password --><inputtype="text"name="registrationpassword"value="xyz123"><inputtype="submit"name="registrationForm"value="Register"><!--SUBMIT Button 3 --></form></fieldset></body></html>
formaction
. O vea la respuesta de kiril sobre cómo hacer que el HTML sea visible para el usuario sea independiente del valor enviado al navegador, resolviendo el problema de internacionalización de una manera más fácil de codificar que la respuesta de Greg o Parrot.Respuestas:
Si le da un nombre a cada uno, el clic será enviado como cualquier otra entrada.
fuente
formaction
. O vea la respuesta de kiril sobre cómo hacer que el HTML sea visible para el usuario sea independiente del valor enviado al navegador, resolviendo el problema de internacionalización.Solución 1:
asigne a cada entrada un valor diferente y mantenga el mismo nombre:
Luego, en el código, verifique qué se activó:
El problema con eso es que vincula su lógica al texto visible para el usuario dentro de la entrada.
Solución 2:
asigne a cada uno un nombre único y compruebe $ _POST para ver si existe esa entrada:
Y en el código:
fuente
Una solución aún mejor consiste en usar etiquetas de botón para enviar el formulario:
El HTML dentro del botón (por ejemplo,
..>Update<..
es lo que ve el usuario; porque se proporciona HTML,value
no es visible para el usuario; solo se envía al servidor. De esta manera no hay inconveniente con la internacionalización y los múltiples idiomas de visualización (en el antigua solución, la etiqueta del botón también es el valor enviado al servidor).fuente
<button>
:submit
yreset
. Tenga en cuenta quereset
no envía nada, solo restablece el formulario. Entonces el argumento de Jeroen permanece.Hay un nuevo enfoque HTML5 para esto, el
formaction
atributo:Aparentemente, esto no funciona en IE9 y versiones anteriores, pero para otros navegadores debería estar bien (vea: w3schools.com HTML <button> formaction Attribute ).
Personalmente, generalmente uso Javascript para enviar formularios de forma remota (para una retroalimentación percibida más rápida) con este enfoque como copia de seguridad. Entre los dos, las únicas personas que no están cubiertas son IE <9 con Javascript deshabilitado.
Por supuesto, esto puede ser inapropiado si básicamente está tomando la misma acción del lado del servidor, independientemente de qué botón se haya presionado, pero a menudo si hay dos acciones del lado del usuario disponibles, también se asignarán a dos acciones del lado del servidor.
Editar: como señaló Pascal_dher en los comentarios, este atributo también está disponible en la
<input>
etiqueta.fuente
form_tag
. La única forma de hacerlo funcionar es cambiarform_for
y usarf.submit formaction: 'your_path'
.formaction
en MDNEsto es extremadamente fácil de probar
Simplemente colóquelo en una página HTML, haga clic en los botones y mire la URL
fuente
Use el
formaction
atributo HTML (5ª línea):fuente
fuente
input
etiqueta en lugar de labutton
etiqueta.La mejor manera de lidiar con el botón de envío múltiple es mediante el uso de mayúsculas y minúsculas en la secuencia de comandos del servidor
código del servidor / secuencia de comandos del servidor - donde está enviando el formulario:
demo_form.php
Fuente: W3Schools.com
fuente
<form action="demo_form.php" method="get">
Quizás las soluciones sugeridas aquí funcionaron en 2009, pero he probado todas estas respuestas votadas y nadie está trabajando en ningún navegador.
La única solución que encontré que funciona es esta: (pero creo que es un poco feo de usar)
fuente
formaction="actionurl1"
? No necesitas JavaScript.formaction
Definir
name
comoarray
.Ejemplo de código de servidor (PHP):
elseif
muy importante, porque ambos se analizarán si no. Disfrutar.fuente
switch
con una acción predeterminada si uno ha agregado un botón y se olvidó de agregarlo aswitch
(y / o escribir mal algo, etc.)Como no especificó qué método de script del lado del servidor está utilizando, le daré un ejemplo que funciona para Python, usando CherryPy (aunque también puede ser útil para otros contextos):
En lugar de usar el valor para determinar qué botón se presionó, puede usar el nombre (con la
<button>
etiqueta en lugar de<input>
). De esa forma, si sus botones tienen el mismo texto, no causará problemas. Los nombres de todos los elementos del formulario, incluidos los botones, se envían como parte de la URL. En CherryPy, cada uno de ellos es un argumento para un método que hace el código del lado del servidor. Entonces, si su método solo tiene**kwargs
su lista de parámetros (en lugar de escribir tediosamente cada nombre de cada elemento del formulario), puede verificar qué botón se presionó de esta manera:fuente
fuente
Creo que debería poder leer el nombre / valor en su matriz GET. Creo que el botón en el que no se hizo clic no aparecerá en esa lista.
fuente
También puede hacerlo así (creo que es muy conveniente si tiene N entradas).
Un caso de uso común sería usar diferentes identificadores de una base de datos para cada botón, para que luego pueda saber en el servidor en qué fila se hizo clic.
En el lado del servidor (PHP en este ejemplo) puede leer "fila" como una matriz para obtener la identificación.
$_POST['row']
será una matriz con solo un elemento, en la forma[ id => value ]
(por ejemplo:)[ '123' => 'something' ]
.Entonces, para obtener la identificación clicada, debes:
http://php.net/manual/en/function.key.php
fuente
$_POST['row']
ser una matriz asociativa es inteligente!Tu formación para botón de envío múltiple en un ejemplo de formulario
fuente
Simple puede cambiar la acción del formulario en diferentes botones de enviar Haga clic.
Pruebe esto en el documento.
fuente
También puede usar un atributo href y enviar un get con el valor agregado para cada botón. Pero el formulario no sería requerido entonces
fuente
POST
rutas.GET
no siempre es adecuado. Si "modifica el estado de su modelo" , nunca debería usar aGET
, ya que la actualización del navegador podría generar el envío transparente de dos veces la misma solicitud. ÚseloGET
solo para "ver" cosas yPOST
enviar solicitudes de cambios de estado (agregar, eliminar, editar, etc.). luego, en laPOST
acción del controlador, altere el estado (base de datos, sesion ...) y emita una respuesta de redireccionamiento que luego seaGET
el nuevo estado alterado. Hacer laGET
alteración del estado del modelo es muy sucio y cualquier buen codificador debería evitarlo. Lamento decir eso. Código limpio rulez.Puede presentar los botones de esta manera:
Y luego, en el código, puede obtener el valor usando:
(valUnits y valPrice son algunos otros valores que extraigo del formulario que dejé como ilustración)
fuente
Como no especificó qué método de script del lado del servidor está utilizando, le daré un ejemplo que funciona para PHP
Formas
Cuando haga clic en Iniciar sesión -> loginForm
Cuando haga clic en Guardar -> saveForm
Cuando haga clic en Registrarse -> RegistrationForm
fuente