Si se envía un formulario pero no mediante un botón específico, como
- presionando Enter
- utilizando
HTMLFormElement.submit()
en JS
¿Cómo se supone que un navegador determina cuál de los múltiples botones de envío, si los hay, usar como el que se presiona?
Esto es significativo en dos niveles:
- llamar a un
onclick
controlador de eventos adjunto a un botón de envío - los datos enviados de vuelta al servidor web
Mis experimentos hasta ahora han demostrado que:
- al presionar Enter, Firefox, Opera y Safari usan el primer botón de enviar en el formulario
- Al presionar Enter, IE utiliza el primer botón de envío o ninguno, dependiendo de las condiciones que no he podido resolver
- todos estos navegadores no usan ninguno para enviar JS
¿Qué dice el estándar?
Si eso ayudara, aquí está mi código de prueba (el PHP es relevante solo para mi método de prueba, no para mi pregunta en sí)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
</head>
<body>
<h1>Get</h1>
<dl>
<?php foreach ($_GET as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<h1>Post</h1>
<dl>
<?php foreach ($_POST as $k => $v) echo "<dt>$k</dt><dd>$v</dd>"; ?>
</dl>
<form name="theForm" method="<?php echo isset($_GET['method']) ? $_GET['method'] : 'get'; ?>" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>">
<input type="text" name="method" />
<input type="submit" name="action" value="Button 1" onclick="alert('Button 1'); return true" />
<input type="text" name="stuff" />
<input type="submit" name="action" value="Button 2" onclick="alert('Button 2'); return true" />
<input type="button" value="submit" onclick="document.theForm.submit();" />
</form>
</body></html>
fuente
HTML 4 no lo hace explícito. El borrador de trabajo HTML5 actual especifica que el primer botón de envío debe ser el predeterminado :
fuente
Andrezj prácticamente lo tiene clavado ... pero aquí hay una solución fácil para varios navegadores.
Toma una forma como esta:
y refactorizar esto:
Dado que la especificación del W3C indica que varios botones de envío son válidos, pero omite la orientación sobre cómo debe manejarlos el agente de usuario, los fabricantes de navegadores deben implementarlos como mejor les parezca. Descubrí que enviarán el primer botón de envío en el formulario o enviarán el siguiente botón de envío después del campo del formulario que actualmente tiene el foco.
Desafortunadamente, simplemente agregando un estilo de visualización: ninguno; no funcionará porque la especificación W3C indica que cualquier elemento oculto debe excluirse de las interacciones del usuario. ¡Así que escóndelo a la vista!
Arriba hay un ejemplo de la solución que terminé poniendo en producción. Al presionar la tecla Intro, el envío de formulario predeterminado es el comportamiento esperado, incluso cuando otros valores no predeterminados están presentes y preceden al botón de envío predeterminado en el DOM. Bonificación por la interacción del mouse / teclado con entradas explícitas del usuario mientras se evitan los controladores javascript.
Nota: la tabulación a través del formulario no mostrará el foco de ningún elemento visual, pero aún hará que se seleccione el botón invisible. Para evitar este problema, simplemente configure los atributos tabindex en consecuencia y omita un atributo tabindex en el botón de envío invisible. Si bien puede parecer fuera de lugar promover estos estilos como importantes, deben evitar que cualquier marco o estilos de botones existentes interfieran con esta solución. Además, esos estilos en línea son definitivamente deficientes, pero aquí estamos probando conceptos ... no escribiendo código de producción.
fuente
<div style="position: fixed; left: -1000px; top: -1000px />
. Solo una cosa más para preocuparse: solo minimizar o alejar el botón del flujo de la página con CSS puede generar problemas de WAI, porque los lectores de pantalla aún verán el botón predeterminado.<input/>
?Creo que esta publicación ayudaría si alguien quiere hacerlo con jQuery:
http://greatwebguy.com/programming/dom/default-html-button-submit-on-enter-with-jquery/
La solución básica es:
y otro que me gustó fue:
fuente
.wich
atributo. Tampoco es necesario recurrir a DOM.keyCode
(o.charCode
para el caso).e.preventDefault();
al comienzo de esta función para evitar la ejecución del botón predeterminado "real". Funciona muy bienTenía un formulario con 11 botones de envío, y siempre usaría el primer botón de envío cuando el usuario presionó enter. Leí en otra parte que no es una buena idea (mala práctica) tener más de un botón de envío en un formulario, y la mejor manera de hacerlo es tener el botón que desea por defecto, como el único botón de envío en el formulario. Los otros botones deben estar en "TYPE = BUTTON" y se debe agregar un evento onClick que llame a su propia rutina de envío en Javascript. Algo como esto :-
Aquí, button3 es el valor predeterminado, y aunque envía el formulario mediante programación con los otros botones, la rutina mjsubmit los valida. HTH
fuente
Esto ahora se puede resolver usando
flexbox
:HTML
CSS
Explicación
Utilización del cuadro de flexión, se puede invertir el orden de los elementos en un recipiente que los usos
display: flex
también usando la regla CSS:flex-direction: row-reverse
. Esto no requiere CSS ni elementos ocultos. Para los navegadores más antiguos que no son compatibles con flexbox, aún obtienen una solución viable, pero los elementos no se revertirán.Demo
http://codepen.io/Godwin/pen/rLVKjm
fuente
Luché con la misma pregunta ya que tenía el botón de envío en el medio del cual se envió el envío redirigido a otra página, así:
Cuando el usuario presionó la tecla Intro, se hizo clic en este botón en lugar de otro botón de envío.
Así que hice algunas pruebas primitivas creando un desde múltiples botones de envío y diferentes opciones de visibilidad y un evento de clic que alertaba en qué botón se hizo clic: https://jsfiddle.net/aqfy51om/1/
Navegadores y sistemas operativos que utilicé para las pruebas:
Ventanas
OSX
La mayoría de estos navegadores hicieron clic en el primer botón a pesar de las opciones de visibilidad aplicadas, excepto IE y Safari, que hicieron clic en el tercer botón, que es "visible" dentro del contenedor "oculto":
Entonces, mi sugerencia, que voy a usar yo mismo, es:
Si su formulario tiene varios botones de envío con un significado diferente, incluya el botón de envío con acción predeterminada al comienzo del formulario, que es:
style="width: 0; height: 0; overflow: hidden;"
EDITAR Otra opción podría ser compensar el botón (aún al comienzo de from)
style="position: absolute; left: -9999px; top: -9999px;"
, solo lo intenté en IE, funcionó, pero no tengo idea de qué más puede arruinar, por ejemplo, imprimir ...fuente
De tus comentarios:
Dejo caer un
<input type="hidden" value="form_name" />
en cada formulario.Si se envía con javascript: agregue eventos de envío a formularios, no haga clic en eventos en sus botones. Los usuarios de Saavy no tocan el mouse con mucha frecuencia.
fuente
Cuando tiene varios botones de envío en un solo formulario y un usuario presiona la tecla ENTRAR para enviar el formulario desde un campo de texto, este código anula la funcionalidad predeterminada, llamando al evento de envío en el formulario desde el evento de presión de tecla. Aquí está ese código:
fuente
Es extraño que el primer botón Enter vaya siempre al primer botón, independientemente de si es visible o no, por ejemplo, usando jquery
show/hide()
. Agregar atributo.attr('disabled', 'disabled')
impide recibir el botón Enviar enviar completamente. Es un problema, por ejemplo, al ajustar la visibilidad del botón Insertar / Editar + Eliminar en los cuadros de diálogo de grabación. Encontré menos hackeo y colocación simple Editar delante de Insertary usa el código javascript:
fuente
mi receta:
Enviará el campo oculto predeterminado si no se hace clic en ninguno de los botones.
si se hace clic, tienen preferencia y se pasa su valor.
fuente
Otra solución que he usado es tener solo un botón en el formulario y falsificar los otros botones.
Aquí hay un ejemplo:
Luego estilo los elementos span para que parezca un botón. Un oyente JS observa el lapso y realiza la operación deseada una vez que se hace clic.
No necesariamente es adecuado para todas las situaciones, pero al menos es bastante fácil de hacer.
fuente
De la especificación HTML 4 :
Esto significa que, dado más de 1 botón de envío y ninguno activado (hecho clic), ninguno debería tener éxito.
Y diría que esto tiene sentido: imagina una forma enorme con múltiples botones de envío. En la parte superior, hay un botón "eliminar este registro", luego siguen muchas entradas y en la parte inferior hay un botón "actualizar este registro". Un usuario que presiona enter mientras está en un campo en la parte inferior del formulario nunca sospechará que golpea implícitamente el "borrar este registro" desde la parte superior.
Por lo tanto, creo que no es una buena idea usar el primer botón o cualquier otro botón que el usuario no defina (haga clic). Sin embargo, los navegadores lo están haciendo, por supuesto.
fuente
EDITAR: Lo siento, al escribir esta respuesta estaba pensando en enviar botones en el sentido general. La respuesta a continuación no se trata de varios
type="submit"
botones, ya que deja solo unotype="submit"
y cambia el otro atype="button"
. Dejo la respuesta aquí como referencia en caso de que ayude a alguien que pueda cambiar eltype
forma:Para determinar qué botón se presiona al presionar enter, puede marcarlo con
type="submit"
, y los otros botones lo marcan contype="button"
. Por ejemplo:fuente