¿Cómo evitar que se envíe el formulario?

245

Tengo un formulario que tiene un botón de enviar en alguna parte.

Sin embargo, me gustaría de alguna manera 'atrapar' el evento de envío y evitar que ocurra.

¿Hay alguna manera de que pueda hacer esto?

No puedo modificar el botón Enviar, porque es parte de un control personalizado.

Nathan Osman
fuente
Aún puede acceder al botón de envío. Renderice la página y tome su ClientID viendo la fuente de la página. Luego, usando algo como jQuery, podría hacer algo como $ ('# ctl01_cph01_controlBtn1'). Click (function () {return false;});
rebelde
@Rafael: Cierto ... pero eso sería un último recurso, este es un control muy complejo.
Nathan Osman
@Raf está basado en asp.net, y tampoco es una mejor práctica. Pero es esencialmente correcto. Simplemente evitaría mirar en la fuente y usar el nombre del control, ya que puede cambiar si alguien edita la página. Efectos secundarios no deseados y tal.

Respuestas:

261

A diferencia de las otras respuestas, el retorno falsees solo una parte de la respuesta. Considere el escenario en el que se produce un error JS antes de la declaración de devolución ...

html

<form onsubmit="return mySubmitFunction(event)">
  ...
</form>

guión

function mySubmitFunction()
{
  someBug()
  return false;
}

volver falseaquí no se ejecutará y el formulario se enviará de cualquier manera. También debe llamar preventDefaultpara evitar la acción de formulario predeterminada para los envíos de formularios Ajax.

function mySubmitFunction(e) {
  e.preventDefault();
  someBug();
  return false;
}

En este caso, incluso con el error, el formulario no se enviará.

Alternativamente, try...catchse podría usar un bloque.

function mySubmit(e) { 
  e.preventDefault(); 
  try {
   someBug();
  } catch (e) {
   throw new Error(e.message);
  }
  return false;
}
Ben Rowe
fuente
44
¿Por qué no regresar falsedirectamente de onsumbit?
ProfK
1
Es posible que desee mostrar un mensaje de error al usuario en el envío. Por ejemplo, "complete este campo obligatorio y luego envíe". En ese caso event.preventDefault será muy útil
Mark Chorley
1
@ProfK si usa event.preventDefault () no importará independientemente, try / catch solo sería parte de su manejo de errores
Ben Rowe
11
<form onsubmit = "return mySubmitFunction (event)"> funcionó ... tuvo que usar la palabra evento entre paréntesis en firefox
danday74
55
@BenRowe Debe agregar el parámetro evt al método llamado. (<form onsubmit="return mySubmitFunction(evt)">)De lo contrario, da un error indefinido.
UfukSURMEN
143

Puedes usar eventos en línea onsubmitcomo este

<form onsubmit="alert('stop submit'); return false;" >

O

<script>
   function toSubmit(){
      alert('I will not submit');
      return false;
   }
</script>

<form onsubmit="return toSubmit();" >

Manifestación

Ahora, esto puede no ser una buena idea al hacer grandes proyectos. Es posible que deba utilizar los oyentes de eventos.

Por favor leer más sobre Inline Eventos vs detectores de eventos addEventListener (y attachEvent de IE) aquí . Porque no puedo explicarlo más de lo que lo hizo Chris Baker .

Ambos son correctos, pero ninguno de ellos es el "mejor" per se, y puede haber una razón por la cual el desarrollador eligió usar ambos enfoques.

Reigel
fuente
Agradable, solución rápida en el camino.
Fernando Torres
Por alguna razón, <form onsubmit="return false;" >no funciona para mí.
Ruan
102

Adjunte un detector de eventos al formulario usando .addEventListener()y luego llame al .preventDefault()método en event:

const element = document.querySelector('form');
element.addEventListener('submit', event => {
  event.preventDefault();
  // actual logic, e.g. validate the form
  console.log('Form submission cancelled.');
});
<form>
  <button type="submit">Submit</button>
</form>

Creo que es una mejor solución que definir un submitcontrolador de eventos en línea con el onsubmitatributo porque separa la lógica y la estructura de la página web. Es mucho más fácil mantener un proyecto donde la lógica está separada del HTML. Ver: JavaScript discreto .

Usar la .onsubmitpropiedad del formobjeto DOM no es una buena idea porque evita que se adjunten múltiples devoluciones de llamada de envío a un elemento. Ver addEventListener vs onclick .

Michał Perłakowski
fuente
1
& para jquery: $("button").click(function(e) { e.preventDefault() });
Nixen85
2
+1 no sé por qué todas las otras respuestas siguen usando envíos en línea, ya que OP mencionó que no puede cambiar el botón (lo que significa que probablemente tampoco pueda cambiar la forma). Preguntándome si hay una manera de obtener el 'formulario' si tenemos la identificación del botón
Robert Sinclair
16

Prueba este ...

código HTML

<form class="submit">
    <input type="text" name="text1"/>
    <input type="text" name="text2"/>
    <input type="submit" name="Submit" value="submit"/>
</form>

Código jQuery

$(function(){
    $('.submit').on('submit', function(event){
        event.preventDefault();
        alert("Form Submission stopped.");
    });
});

o

$(function(){
    $('.submit').on('submit', function(event){
       event.preventDefault();
       event.stopPropagation();
       alert("Form Submission prevented / stopped.");
    });
});
Sach
fuente
18
No hay una etiqueta jQuery en esta pregunta.
Michał Perłakowski
66
@Gothdo y, sin embargo, la solución sigue siendo la misma. loco ¿verdad?
Kevin B
77
@ Gothdo sí, es exactamente lo mismo. eventObject.preventDefault. La forma en que vincula el controlador no cambia la solución. Incluso diría que su respuesta no es diferente a la aceptada.
Kevin B
stopPropagationfue lo único que funcionó en mi caso. ¡Gracias! :)
cregox
13

Lo siguiente funciona a partir de ahora (probado en Chrome y Firefox):

<form onsubmit="event.preventDefault(); return validateMyForm();">

donde validateMyForm () es una función que devuelve falsesi falla la validación. El punto clave es usar el nombre event. No podemos usar por ej.e.preventDefault()

Vikram Pudi
fuente
1
onsubmit = "return validateMyForm ();" es suficiente pero validateMyForm () debería devolver verdadero o falso.
Adrian P.
8
var form = document.getElementById("idOfForm");
form.onsubmit = function() {
  return false;
}
naikus
fuente
2
Creo que usar .onsubmites una mala idea porque evita que se adjunten múltiples submitdevoluciones de llamada a un elemento. Recomiendo usar .addEventListener().
Michał Perłakowski
3
Incluso si ha establecido un controlador de eventos a través de la propiedad .onsubmit, puede agregar controladores adicionales a través de .addEventListener (). El controlador registrado por la propiedad se invocará primero y luego los registrados con .addEventListener () en el orden en que se registraron.
Daniel Granger
2

Para seguir convenciones de programación de JavaScript discretas , y dependiendo de qué tan rápido se cargue el DOM , puede ser una buena idea usar lo siguiente:

<form onsubmit="return false;"></form>

Luego, conecte eventos usando la carga o DOM listo si está usando una biblioteca.

$(function() {
    var $form = $('#my-form');
    $form.removeAttr('onsubmit');
    $form.submit(function(ev) {
        // quick validation example...
        $form.children('input[type="text"]').each(function(){
            if($(this).val().length == 0) {
                alert('You are missing a field');
                ev.preventDefault();
            }
        });
    });
});
label {
    display: block;
}

#my-form > input[type="text"] {
    background: cyan;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="my-form" action="http://google.com" method="GET" onsubmit="return false;">
    <label>Your first name</label>
    <input type="text" name="first-name"/>
    <label>Your last name</label>
    <input type="text" name="last-name" /> <br />
    <input type="submit" />
</form>

Además, siempre usaría el actionatributo ya que algunas personas pueden tener algún complemento como NoScript en ejecución que luego rompería la validación. Si está utilizando el atributo action, al menos su usuario será redirigido por el servidor en función de la validación de back-end. Si estás usando algo como window.location, por otro lado, las cosas serán malas.

Sebastian Palma
fuente
2

Para evitar que se envíe el formulario, solo necesita hacer esto.

<form onsubmit="event.preventDefault()">
    .....
</form>

Al usar el código anterior, esto evitará el envío de su formulario.

Zuhair Taha
fuente
0

Aquí mi respuesta:

<form onsubmit="event.preventDefault();searchOrder(event);">
...
</form>
<script>
const searchOrder = e => {
    e.preventDefault();
    const name = e.target.name.value;
    renderSearching();

    return false;
}
</script>

Añado event.preventDefault();en onsubmity funciona.

yozawiratama
fuente
0

Puede agregar eventListner al formulario preventDefault()y convertir los datos del formulario a JSON de la siguiente manera:

const formToJSON = elements => [].reduce.call(elements, (data, element) => {
  data[element.name] = element.value;
  return data;

}, {});

const handleFormSubmit = event => {
    event.preventDefault();
    const data = formToJSON(form.elements);
    console.log(data);
  //  const odata = JSON.stringify(data, null, "  ");
  const jdata = JSON.stringify(data);
    console.log(jdata);

    (async () => {
      const rawResponse = await fetch('/', {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: jdata
      });
      const content = await rawResponse.json();

      console.log(content);
    })();
};

const form = document.forms['myForm']; 
form.addEventListener('submit', handleFormSubmit);
<form id="myForm" action="/" method="post" accept-charset="utf-8">
    <label>Checkbox:
        <input type="checkbox" name="checkbox" value="on">
    </label><br /><br />

    <label>Number:
        <input name="number" type="number" value="123" />
    </label><br /><br />

    <label>Password:
        <input name="password" type="password" />
    </label>
    <br /><br />

    <label for="radio">Type:
        <label for="a">A
            <input type="radio" name="radio" id="a" value="a" />
        </label>
        <label for="b">B
            <input type="radio" name="radio" id="b" value="b" checked />
        </label>
        <label for="c">C
            <input type="radio" name="radio" id="c" value="c" />
        </label>
    </label>
    <br /><br />

    <label>Textarea:
        <textarea name="text_area" rows="10" cols="50">Write something here.</textarea>
    </label>
    <br /><br />

    <label>Select:
        <select name="select">
            <option value="a">Value A</option>
            <option value="b" selected>Value B</option>
            <option value="c">Value C</option>
        </select>
    </label>
    <br /><br />

    <label>Submit:
        <input type="submit" value="Login">
    </label>
    <br /><br />


</form>

Hasan A Yousef
fuente