jQuery: evita el valor predeterminado, luego continúa el valor predeterminado

102

Tengo un formulario que, cuando se envía, necesito realizar un procesamiento adicional antes de que deba enviar el formulario. Puedo evitar el comportamiento predeterminado de envío de formularios, luego realizar mi procesamiento adicional (básicamente es llamar a la API de Google Maps y agregar algunos campos ocultos al formulario), y luego necesito el formulario para enviar.

¿Hay alguna forma de "evitar el valor predeterminado" y, en algún momento, "continuar predeterminado"?

StackOverflowNewbie
fuente
@FelixKling ¿Quisiste decir stackoverflow.com/questions/7610871/… ?
M. Mimpen

Respuestas:

53

Utilizar jQuery.one()

Adjunte un controlador a un evento para los elementos. El controlador se ejecuta como máximo una vez por elemento por tipo de evento

$('form').one('submit', function(e) {
    e.preventDefault();
    // do your things ...

    // and when you done:
    $(this).submit();
});

El uso de oneprevenir también un bucle infinito porque este submitevento personalizado se separa después del primer envío.

Aurel
fuente
2
se enviará después de hacer clic nuevamente :(
curiosidad
Probablemente te enfrentes con bucle infinito
Mehrdad HosseinNejad
Bucle infinito, la función debe ser .on no .one
sgvolpe
51

Cuando unes el .submit() evento al formulario y hace las cosas que desea hacer antes de regresar (verdadero), estas cosas suceden antes del envío real.

Por ejemplo:

$('form').submit(function(){
    alert('I do something before the actual submission');
    return true;
});

Ejemplo simple

Otro ejemplo en jquery.com: http://api.jquery.com/submit/#entry-examples

Ron van der Heijden
fuente
2
¿Está diciendo que el formulario no se enviará hasta que todo el código antes de "return true"; se ejecuta la sentencia?
Developarvin
2
Sí, eso es exactamente lo que hace la función submit () .
Ron van der Heijden
8
No es un buen ejemplo porque es sincrónico. ¿Qué pasa si lo que tengo que hacer es una llamada asíncrona? Entonces, el caso es "haga clic en enviar -> haga cosas asincrónicas y no envíe el formulario -> en la devolución de llamada asíncrona complete algunos campos en el formulario -> envíe el formulario desde la devolución de llamada"
El Padrino
1
¿Qué tal ejecutar código jQuery asincrónico? ¿Funcionará también?
Candlejack
esto funciona muy bien para mí. Lo uso para controlar cosas antes de enviar y si las cosas no están bien, uso "devolver falso". He buscado esta solución durante un día. muchas gracias.
livefreeor
26

Yo solo haría:

 $('#submiteButtonID').click(function(e){
     e.preventDefault();
     //do your stuff.
     $('#formId').submit();
 });

Llame preventDefaultal principio y use la submit()función más tarde, si solo necesita enviar el formulario

bipen
fuente
no involucre la lógica dentro de su controlador de eventos de clic. delegarlo en otros.
Royi Namir
27
Esto supone que el seguro hará clic en un botón. ¿Qué pasa si el usuario simplemente presiona el botón "ingresar" desde el formulario? Eso también enviará el formulario. Por lo tanto, probablemente no sea una buena idea confiar en que se haga clic en el botón Enviar.
StackOverflowNewbie
Solo estaba dando un ejemplo de un clic ... ya que no se mencionaron códigos relacionados en la pregunta ...
bipen
2
En cualquier caso, el fragmento que proporcionó solo funcionará si el usuario hace clic en un botón. No es así como funcionan los formularios. ¿Cualquier otra sugerencia?
StackOverflowNewbie
se unen el clic, prevenir su defecto y activar el botón de envío clic
candlejack
18

De esta manera, hará un bucle sin fin en su JS. para hacerlo de una mejor manera, puede utilizar lo siguiente

var on_submit_function = function(evt){
    evt.preventDefault(); //The form wouln't be submitted Yet.
    (...yourcode...)

    $(this).off('submit', on_submit_function); //It will remove this handle and will submit the form again if it's all ok.
    $(this).submit();
}

$('form').on('submit', on_submit_function); //Registering on submit.

¡Espero que ayude! ¡Gracias!

Joepreludian
fuente
la mejor manera en realidad, variación con la función asíncrona - gist.github.com/BjornMelgaard/8ba0ee9d07c20dd8c8b3550c9df3e9ef
srghma
@bjornmelgaard Tengo que recordar que el async no es estándar .
Valerio Bozz
6

Esta es, en mi humilde opinión, la solución más genérica y robusta (si sus acciones son activadas por el usuario, por ejemplo, 'el usuario hace clic en un botón'):

  • la primera vez que se llama a un manejador comprobar QUIÉN lo activó:
    • si un usuario lo activó, haga sus cosas y luego vuelva a activarlo (si lo desea), mediante programación
    • de lo contrario, no hacer nada (= "continuar predeterminado")

Como ejemplo, observe esta elegante solución para agregar "¿Está seguro?" emergente a cualquier botón simplemente decorando un botón con un atributo. Continuaremos condicionalmente el comportamiento predeterminado si el usuario no se excluye.

1. Agreguemos un texto de advertencia a cada botón que deseemos con un mensaje emergente de "¿estás seguro?"

<button class="btn btn-success-outline float-right" type="submit"  ays_text="You will lose any unsaved changes... Do you want to continue?"                >Do something dangerous</button>

2. Adjunte controladores a TODOS esos botones:

$('button[ays_text]').click(function (e, from) {
    if (from == null) {  // user clicked it!
        var btn = $(this);
        e.preventDefault();
        if (confirm() == true) {
            btn.trigger('click', ['your-app-name-here-or-anything-that-is-not-null']);
        }
    }
    // otherwise - do nothing, ie continue default
});

Eso es.

igorludi
fuente
1
¡Gran respuesta! No sabía que se podía pasar un argumento adicional a .trigger ()
James Hibbard
5
$('#myform').on('submit',function(event){
  // block form submit event
  event.preventDefault();

  // Do some stuff here
  ...

  // Continue the form submit
  event.currentTarget.submit();
});
Udayantha Udy Warnasuriya
fuente
3

Con jQuery una pequeña variación de la respuesta de @Joepreludian anterior:

Puntos importantes a tener en cuenta:

  • .one(...) En vez de .on(...) or .submit(...)
  • namedfunción en lugar de, anonymous functionya que la referiremos dentro de callback.

$('form#my-form').one('submit', function myFormSubmitCallback(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    var $this = $(this);
    if (allIsWell) {
        $this.submit(); // submit the form and it will not re-enter the callback because we have worked with .one(...)
    } else {
        $this.one('submit', myFormSubmitCallback); // lets get into the callback 'one' more time...
    }
});

Puede cambiar el valor de la allIsWellvariable en el siguiente fragmento trueo falseprobar la funcionalidad:

$('form#my-form').one('submit', function myFormSubmitCallback(evt){
  evt.stopPropagation();
  evt.preventDefault();
  var $this = $(this);
  var allIsWell = $('#allIsWell').get(0).checked;
  if(allIsWell) {
    $this.submit();
  } else {
    $this.one('submit', myFormSubmitCallback);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="/" id="my-form">
  <input name="./fname" value="John" />
  <input name="./lname" value="Smith" />
  <input type="submit" value="Lets Do This!" />
  <br>
  <label>
    <input type="checkbox" value="true" id="allIsWell" />
    All Is Well
  </label>
</form>

Buena suerte...

Akash
fuente
2

De forma pura con Javascript, puede enviar el formulario después de evitar el incumplimiento.

Esto se debe a que HTMLFormElement.submit() nunca llama al onSubmit(). Por lo tanto, confiamos en esa rareza de la especificación para enviar el formulario como si no tuviera un controlador onsubmit personalizado aquí.

var submitHandler = (event) => {
  event.preventDefault()
  console.log('You should only see this once')
  document.getElementById('formId').submit()
}

Vea este violín para una solicitud sincrónica.


Esperar a que finalice una solicitud asincrónica es igual de fácil:

var submitHandler = (event) => {
  event.preventDefault()
  console.log('before')
  setTimeout(function() {
    console.log('done')
    document.getElementById('formId').submit()
  }, 1400);
  console.log('after')
}

Puede consultar mi violín para ver un ejemplo de una solicitud asincrónica.


Y si estás deprimido con promesas:

var submitHandler = (event) => {
  event.preventDefault()
  console.log('Before')
    new Promise((res, rej) => {
      setTimeout(function() {
        console.log('done')
        res()
      }, 1400);
    }).then(() => {
      document.getElementById('bob').submit()
    })
  console.log('After')
}

Y aquí está esa solicitud .

alairock
fuente
1

Puedes usar e.preventDefault() que detendrá la operación actual.

de lo que puedes hacer$("#form").submit();

 $('#form').submit(function (e)
{
    return !!e.submit;
});
if(blabla...)
{...
}
else
{
    $('#form').submit(
    {
        submit: true
    });
}
Royi Namir
fuente
esto es muy confuso para mí ... ¿no va a dar vueltas y vueltas?
dapidmini
1

"Inyección de validación sin bucle de envío":

Solo quiero verificar reCaptcha y algunas otras cosas antes de la validación de HTML5, así que hice algo así (la función de validación devuelve verdadero o falso):

$(document).ready(function(){
   var application_form = $('form#application-form');

   application_form.on('submit',function(e){

        if(application_form_extra_validation()===true){
           return true;
        }

        e.preventDefault();

   });
});
Dennis Heiden
fuente