Múltiples botones de envío en un formulario HTML

263

Supongamos que crea un asistente en un formulario HTML. Un botón retrocede y el otro avanza. Como el botón Atrás aparece primero en el marcado cuando presiona Enter, usará ese botón para enviar el formulario.

Ejemplo:

<form>
  <!-- Put your cursor in this field and press Enter -->
  <input type="text" name="field1" />

  <!-- This is the button that will submit -->
  <input type="submit" name="prev" value="Previous Page" />

  <!-- But this is the button that I WANT to submit -->
  <input type="submit" name="next" value="Next Page" />
</form>

Me gustaría decidir qué botón se utiliza para enviar el formulario cuando un usuario presiona Enter. De esa manera, cuando presiona Enterel asistente se moverá a la página siguiente, no a la anterior. ¿Tienes que usar tabindexpara hacer esto?

Kevin
fuente

Respuestas:

142

Espero que esto ayude. Solo estoy haciendo el truco de floatpresionar los botones a la derecha.

De esta manera, el Prevbotón queda a la izquierda del Nextbotón, pero el Nextprimero es primero en la estructura HTML:

.f {
  float: right;
}
.clr {
  clear: both;
}
<form action="action" method="get">
  <input type="text" name="abc">
  <div id="buttons">
    <input type="submit" class="f" name="next" value="Next">
    <input type="submit" class="f" name="prev" value="Prev">
    <div class="clr"></div><!-- This div prevents later elements from floating with the buttons. Keeps them 'inside' div#buttons -->
  </div>
</form>

Beneficios sobre otras sugerencias: sin código JavaScript, accesible, y ambos botones permanecen type="submit".

palotasb
fuente
23
No haga esto sin cambiar también el orden de las pestañas, de modo que al presionar el botón de pestañas se desplazará por los botones tal como aparecen en la pantalla.
Steve
61

Cambie el tipo de botón anterior en un botón como este:

<input type="button" name="prev" value="Previous Page" />

Ahora el botón Siguiente sería el predeterminado, además de que también podría agregarle el defaultatributo para que su navegador lo resalte así:

<input type="submit" name="next" value="Next Page" default />
Wally Lawless
fuente
39
¿De qué defaultatributo estás hablando? No hay un atributo "predeterminado", que sería válido: w3.org/html/wg/drafts/html/master/… (no en HTML5, HTML 4.01 Transitional / Strict, XHTML 1.0 Strict). Y no veo por qué sería mejor cambiar el tipo de entrada de submita button. Puede tener múltiples elementos de entrada de tipo de envío en un formulario sin ningún problema. Realmente no entiendo por qué esta respuesta es tan votada.
Sk8erPeter
3
Tener una entrada de tipo "botón" no ejecuta la acción del formulario. Puede tener un onclick o algo así, ejecutando así otra función que no sea la acción de formulario "predeterminada" (que se ejecuta presionando el botón de tipo "enviar"). Eso es lo que estaba buscando y por eso lo voté. No puedo hablar por el atributo "predeterminado", no fue parte de mi problema;) gracias por su aclaración, sin embargo.
Jonas
2
@ Sk8erPeter, @Jonas .... hmm .. Sospecho que este defaultatributo es un atributo Global; atributo enumerado ... que está relacionado con los estados de enumeración: w3.org/html/wg/drafts/html/master/… . aparte de ese punto ... el aspecto del botón de esta respuesta no es una respuesta ... es una ' sugerencia condicional ' o una consulta ( pregunta en sí misma ).
Brett Caswell
3
@Jonas: sí, type="button"no envía el formulario, type="submit"sí, pero cambiar el tipo de estos botones definitivamente no es una solución, porque estos botones deberían comportarse básicamente de la misma manera: la pregunta del OP fue cómo hacer que el botón "Siguiente" predeterminado para presionar la tecla Enter. Y hay una posible solución en la respuesta aceptada.
Sk8erPeter
44
@BrettCaswell: cambiar el tipo de estos botones es una mala solución (ver mi comentario anterior). No hay un defaultatributo válido para las inputetiquetas (como dije anteriormente) en HTML, y los navegadores (populares) NO resaltarán el botón que tiene este atributo, lo que significa que no hay una implementación no estándar de este atributo, por lo que todavía no lo sé de qué estaba hablando @Wally Lawless y por qué esta respuesta está tan sobrevalorada. Solo hay un defaultatributo válido introducido en HTML5, PERO solo para la <track>etiqueta: developer.mozilla.org/en-US/docs/Web/HTML/Element/track
Sk8erPeter
56

Dé a sus botones de envío el mismo nombre de esta manera:

<input type="submit" name="submitButton" value="Previous Page" />
<input type="submit" name="submitButton" value="Next Page" />

Cuando el usuario presiona Entery la solicitud va al servidor, puede verificar el valor submitButtonen su código del lado del servidor que contiene una colección de name/valuepares de formularios . Por ejemplo, en ASP Classic :

If Request.Form("submitButton") = "Previous Page" Then
    ' Code for the previous page
ElseIf Request.Form("submitButton") = "Next Page" Then
    ' Code for the next page
End If

Referencia: uso de varios botones de envío en un solo formulario

huseyint
fuente
26
Esto no es lo que preguntó el usuario. El usuario quería saber cómo controlar qué botón de envío en un formulario se activa cuando se presiona enter, es decir. cual es el botón por defecto.
kosoant
20
no funciona en una aplicación I18n donde ni siquiera conoce la etiqueta del botón.
Chris
¿En qué sistema o solución tecnológica el servidor mismo no sabría cuál es la etiqueta que se usó para el botón Siguiente y Atrás? ¿No generó el servidor el botón Siguiente y Atrás en primer lugar? (Si la localización se maneja en el lado del cliente, imagino que el servidor puede no saberlo, pero nunca he oído hablar de esto para HTML)
Jacob
Esta respuesta pierde por completo la pregunta, probablemente sea por una pregunta diferente. ¿Por qué tantos votos a favor? Sin mencionar que uno nunca debe verificar la etiqueta del botón ... requiere muchos problemas. Incluso el caso simple: "debemos abreviar la cadena a 'Página anterior'" arruinará la funcionalidad de sus sitios.
Tylla
30

Si el hecho de que el primer botón se use de manera predeterminada es consistente en todos los navegadores, colóquelos en el código fuente de la manera correcta y luego use CSS para cambiar sus posiciones aparentes.

float izquierda y derecha para cambiarlos visualmente, por ejemplo.

Polsonby
fuente
18

A veces, la solución proporcionada por @palotasb no es suficiente. Hay casos de uso en los que, por ejemplo, se coloca un botón de envío "Filtro" encima de botones como "Siguiente y Anterior". Encontré una solución para esto: copie el botón de envío que debe actuar como el botón de envío predeterminado en un div oculto y colóquelo dentro del formulario sobre cualquier otro botón de envío. Técnicamente, se enviará con un botón diferente al presionar Entrar que al hacer clic en el botón Siguiente visible. Pero como el nombre y el valor son iguales, no hay diferencia en el resultado.

<html>
<head>
    <style>
        div.defaultsubmitbutton {
            display: none;
        }
    </style>
</head>
<body>
    <form action="action" method="get">
        <div class="defaultsubmitbutton">
            <input type="submit" name="next" value="Next">
        </div>
        <p><input type="text" name="filter"><input type="submit" value="Filter"></p>
        <p>Filtered results</p>
        <input type="radio" name="choice" value="1">Filtered result 1
        <input type="radio" name="choice" value="2">Filtered result 2
        <input type="radio" name="choice" value="3">Filtered result 3
        <div>                
            <input type="submit" name="prev" value="Prev">
            <input type="submit" name="next" value="Next">
        </div>
    </form>
</body>
</html>
netiul
fuente
17

Usaría JavaScript para enviar el formulario. La función sería activada por el evento OnKeyPress del elemento de formulario y detectaría si la Enterclave fue seleccionada. Si este es el caso, enviará el formulario.

Aquí hay dos páginas que dan técnicas sobre cómo hacer esto: 1 , 2 . Basado en esto, aquí hay un ejemplo de uso (basado en aquí ):

<SCRIPT TYPE="text/javascript">//<!--
function submitenter(myfield,e) {
  var keycode;
  if (window.event) {
    keycode = window.event.keyCode;
  } else if (e) {
    keycode = e.which;
  } else {
    return true;
  }

  if (keycode == 13) {
    myfield.form.submit();
    return false;
  } else {
    return true;
  }
}
//--></SCRIPT>

<INPUT NAME="MyText" TYPE="Text" onKeyPress="return submitenter(this,event)" />
Yaakov Ellis
fuente
2
¿Qué sucede si javascript está deshabilitado?
Jon Winstanley el
2
No debe usar <! - y -> para comentar JS, estas etiquetas no son tokens de lenguaje Javascript
Marecky
2
@Marecky No deben comentar JS. Se ignoran al analizar el contenido de <script> en un navegador que admite <script>. Hoy realmente no son necesarios. Pero en navegadores muy antiguos, este fue un truco de compatibilidad para evitar que el script se imprima como texto sin formato.
Leemes
17

Si realmente desea que funcione como un cuadro de diálogo de instalación, solo concéntrese en el botón "Siguiente" OnLoad.

De esa manera, si el usuario acierta Return, el formulario se envía y continúa. Si quieren regresar pueden presionar Tabo hacer clic en el botón.

Scott Gottreu
fuente
2
Significan que alguien llena un formulario y presiona regresar mientras está en un campo de texto.
Jordan Reiter el
17

Esto no se puede hacer con HTML puro. Debes confiar en JavaScript para este truco.

Sin embargo, si coloca dos formularios en la página HTML, puede hacerlo.

Form1 tendría el botón anterior.

Form2 tendría cualquier entrada de usuario + el botón siguiente.

Cuando el usuario presiona Enteren Form2, se activará el botón Enviar siguiente.

FlySwat
fuente
16

Puedes hacerlo con CSS.

Coloque los botones en el marcado con el Nextbotón primero, luego el Prevbotón después.

Luego use CSS para colocarlos para que aparezcan de la manera que desee.

qui
fuente
14

Esto funciona sin JavaScript o CSS en la mayoría de los navegadores:

<form>
    <p><input type="text" name="field1" /></p>
    <p><a href="previous.html">
    <button type="button">Previous Page</button></a>
    <button type="submit">Next Page</button></p>
</form>

Firefox, Opera, Safari y Google Chrome funcionan.
Como siempre, Internet Explorer es el problema.

Esta versión funciona cuando JavaScript está activado:

<form>
    <p><input type="text" name="field1" /></p>
    <p><a href="previous.html">
    <button type="button" onclick="window.location='previous.html'">Previous Page</button></a>
    <button type="submit">Next Page</button></p>
</form>

Entonces, la falla en esta solución es:

La página anterior no funciona si usa Internet Explorer con JavaScript desactivado.

Eso sí, el botón de retroceso todavía funciona!

Jolyon
fuente
1
Sin javascript no podrá activar el botón "página anterior", porque el tipo = "botón"!
riskop
El problema con su sugerencia es que un botón type = "button" no publicaría el formulario, por lo que básicamente no hace nada, mientras que la segunda versión con un ancla crearía un GET en lugar de un POST.
Tylla
12

Si tiene varios botones activos en una página, puede hacer algo como esto:

Marque el primer botón que desea activar al presionar la Entertecla como el botón predeterminado en el formulario. Para el segundo botón, asócielo al Backspacebotón del teclado. El Backspacecódigo de evento es 8.

$(document).on("keydown", function(event) {
  if (event.which.toString() == "8") {
    var findActiveElementsClosestForm = $(document.activeElement).closest("form");

    if (findActiveElementsClosestForm && findActiveElementsClosestForm.length) {
      $("form#" + findActiveElementsClosestForm[0].id + " .secondary_button").trigger("click");
    }
  }
});
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>

<form action="action" method="get" defaultbutton="TriggerOnEnter">
  <input type="submit" id="PreviousButton" name="prev" value="Prev" class="secondary_button" />
  <input type="submit" id='TriggerOnEnter' name="next" value="Next" class="primary_button" />
</form>

usuario1591131
fuente
11

Cambiar el orden de tabulación debería ser todo lo que se necesita para lograr esto. Mantenlo simple.

Otra opción simple sería colocar el botón Atrás después del botón Enviar en el código HTML, pero flotarlo a la izquierda para que aparezca en la página antes del botón Enviar.

Kenny Johnson
fuente
10
<input type="submit" name="perv" value="Previous Page"> 
<input type="submit" name="prev" value="Next Page"> 

Mantenga el mismo nombre de todos los botones de envío: "anterior".

La única diferencia es la value atributo con valores únicos. Cuando creamos el script, estos valores únicos nos ayudarán a determinar cuál de los botones de envío se presionó.

Y escriba la siguiente codificación:

    btnID = ""
if Request.Form("prev") = "Previous Page" then
    btnID = "1"
else if Request.Form("prev") = "Next Page" then
    btnID = "2"
end if
jayu
fuente
El problema es que presionar enter en un campo de texto enviará el formulario con el primer botón de envío, no con el deseado (segundo en el ejemplo). ¡Descubrir qué botón de envío se usó para enviar el formulario es fácil, y esa no era la pregunta!
riskop
¿Por qué name="perv"?
Peter Mortensen
10

Otra opción simple sería colocar el botón Atrás después del botón Enviar en el código HTML, pero flotarlo a la izquierda, para que aparezca en la página antes del botón Enviar.

Cambiar el orden de tabulación debería ser todo lo que se necesita para lograr esto. Mantenlo simple.

Peter Mortensen
fuente
10

La primera vez que me topé con esto, se me ocurrió un truco onclick () / JavaScript cuando las opciones no son anteriores / siguientes que todavía me gustan por su simplicidad. Dice así:

@model myApp.Models.myModel

<script type="text/javascript">
    function doOperation(op) {
        document.getElementById("OperationId").innerText = op;
        // you could also use Ajax to reference the element.
    }
</script>

<form>
  <input type="text" id = "TextFieldId" name="TextField" value="" />
  <input type="hidden" id="OperationId" name="Operation" value="" />
  <input type="submit" name="write" value="Write" onclick='doOperation("Write")'/>
  <input type="submit" name="read" value="Read" onclick='doOperation("Read")'/>
</form>

Cuando se hace clic en cualquiera de los botones de envío, almacena la operación deseada en un campo oculto (que es un campo de cadena incluido en el modelo al que está asociado el formulario) y envía el formulario al Controlador, que toma todas las decisiones. En el controlador, simplemente escribe:

// Do operation according to which submit button was clicked
// based on the contents of the hidden Operation field.
if (myModel.Operation == "Read")
{
     // Do read logic
}
else if (myModel.Operation == "Write")
{
     // Do write logic
}
else
{
     // Do error logic
}

También puede ajustar esto ligeramente usando códigos de operación numéricos para evitar el análisis de cadenas, pero a menos que juegue con enumeraciones, el código es menos legible, modificable y autodocumentado y, de todos modos, el análisis es trivial.

De mediana edadMutanteNinjaProgramador
fuente
9

De https://html.spec.whatwg.org/multipage/forms.html#implicit-submission

El botón predeterminado de un elemento de formulario es el primer botón de envío en orden de árbol cuyo propietario de formulario es ese elemento de formulario.

Si el agente de usuario admite permitir que el usuario envíe un formulario implícitamente (por ejemplo, en algunas plataformas, presionar la tecla "enter" mientras un campo de texto está enfocado envía implícitamente el formulario) ...

Tener la siguiente entrada sea type = "submit" y cambiar la entrada anterior a type = "button" debería dar el comportamiento predeterminado deseado.

<form>
   <input type="text" name="field1" /> <!-- put your cursor in this field and press Enter -->

   <input type="button" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
   <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>
nikkypx
fuente
9

Esto es lo que he probado:

  1. Debes asegurarte de darle a tus botones nombres diferentes
  2. Escriba una ifdeclaración que haga la acción requerida si se hace clic en cualquiera de los botones.

 

<form>
    <input type="text" name="field1" /> <!-- Put your cursor in this field and press Enter -->

    <input type="submit" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
    <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

En PHP

if(isset($_POST['prev']))
{
    header("Location: previous.html");
    die();
}

if(isset($_POST['next']))
{
    header("Location: next.html");
    die();
}
Samuel Mugisha
fuente
El problema es que presionar enter en un campo de texto enviará el formulario con el primer botón de envío, no con el deseado (segundo en el ejemplo). ¡Descubrir qué botón de envío se usó para enviar el formulario es fácil, y esa no era la pregunta!
riskop
7

Encontré esta pregunta cuando trataba de encontrar una respuesta básicamente a la misma cosa, solo con los controles ASP.NET, cuando descubrí que el botón ASP tiene una propiedad llamada UseSubmitBehaviorque le permite establecer cuál envía.

<asp:Button runat="server" ID="SumbitButton" UseSubmitBehavior="False" Text="Submit" />

En caso de que alguien esté buscando la forma del botón ASP.NET para hacerlo.

Barry Franklin
fuente
6

Con JavaScript (aquí jQuery), puede deshabilitar el botón prev antes de enviar el formulario.

$('form').on('keypress', function(event) {
    if (event.which == 13) {
        $('input[name="prev"]').prop('type', 'button');
    }
});
GuillaumeS
fuente
1

Prueba esto..!

<form>
  <input type="text" name="Name" />
  <!-- Enter the value -->

  <input type="button" name="prev" value="Previous Page" />
  <!-- This is the button that will submit -->
  <input type="submit" name="next" value="Next Page" />
  <!-- But this is the button that I WANT to submit -->
</form>

Gowtham Balusamy
fuente
1

Resolví un problema muy similar de esta manera:

  1. Si JavaScript está habilitado (en la mayoría de los casos hoy en día), todos los botones de envío se " degradan " a botones al cargar la página a través de JavaScript (jQuery). Los eventos de clic en el botón " degradado " también se manejan a través de JavaScript.

  2. Si JavaScript no está habilitado, el formulario se sirve en el navegador con varios botones de envío. En este caso, presionar Enterun textfieldformulario dentro del formulario enviará el formulario con el primer botón en lugar del valor predeterminado deseado , pero al menos el formulario todavía es utilizable: puede enviarlo con los botones anterior y siguiente .

Ejemplo de trabajo:

<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    </head>

    <body>
        <form action="http://httpbin.org/post" method="post">
            If JavaScript  is disabled, then you CAN submit the form
            with button1, button2 or button3.

            If you press enter on a text field, then the form is
            submitted with the first submit button.

            If JavaScript is enabled, then the submit typed buttons
            without the 'defaultSubmitButton' style are converted
            to button typed buttons.

            If you press Enter on a text field, then the form is
            submitted with the only submit button
            (the one with class defaultSubmitButton)

            If you click on any other button in the form, then the
            form is submitted with that button's value.

            <br />

            <input type="text" name="text1" ></input>
            <button type="submit" name="action" value="button1" >button 1</button>
            <br />

            <input type="text" name="text2" ></input>
            <button type="submit" name="action" value="button2" >button 2</button>
            <br />

            <input type="text" name="text3" ></input>
            <button class="defaultSubmitButton" type="submit" name="action" value="button3" >default button</button>
        </form>

        <script>
            $(document).ready(function(){

                /* Change submit typed buttons without the 'defaultSubmitButton'
                   style to button typed buttons */
                $('form button[type=submit]').not('.defaultSubmitButton').each(function(){
                    $(this).attr('type', 'button');
                });

                /* Clicking on button typed buttons results in:
                   1. Setting the form's submit button's value to
                      the clicked button's value,
                   2. Clicking on the form's submit button */
                $('form button[type=button]').click(function( event ){
                    var form = event.target.closest('form');
                    var submit = $("button[type='submit']",form).first();
                    submit.val(event.target.value);
                    submit.click();
                });
            });
        </script>
    </body>
</html>

riesgo
fuente
0

Puedes usar Tabindexpara resolver este problema. También cambiar el orden de los botones sería una forma más eficiente de lograr esto.

Cambie el orden de los botones y agregue floatvalores para asignarles la posición deseada que desea mostrar en su HTMLvista.

Jyoti mishra
fuente
-4

Usando el ejemplo que diste:

<form>
    <input type="text" name="field1" /><!-- Put your cursor in this field and press Enter -->
    <input type="submit" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
    <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

Si hace clic en "Página anterior", solo se enviará el valor de "anterior". Si hace clic en "Página siguiente", solo se enviará el valor de "siguiente".

Sin embargo, si presiona en Enteralgún lugar del formulario, no se enviarán ni "prev" ni "next".

Entonces, utilizando pseudocódigo, podría hacer lo siguiente:

If "prev" submitted then
    Previous Page was click
Else If "next" submitted then
    Next Page was click
Else
    No button was click
GateKiller
fuente
1
Nunca hay una situación (sin usar js) cuando ninguno de los botones se activa. Si presiona ENTRAR, el primer botón del código capturará el evento. En el ejemplo html es el botón anterior.
SimonSimCity