jQuery - cegah default, lalu lanjutkan default

104

Saya memiliki formulir yang, ketika dikirim, saya perlu melakukan beberapa pemrosesan tambahan sebelum mengirimkan formulir. Saya dapat mencegah perilaku pengiriman formulir default, kemudian melakukan pemrosesan tambahan saya (pada dasarnya memanggil Google Maps API dan menambahkan beberapa bidang tersembunyi ke formulir) - dan kemudian saya memerlukan formulir untuk dikirim.

Apakah ada cara untuk "mencegah default", kemudian beberapa hal kemudian "melanjutkan default?"

StackOverflowNewbie
sumber
@FelixKling Maksud Anda stackoverflow.com/questions/7610871/… ?
M. Mimpen

Jawaban:

53

Saat Anda mengikat .submit()acara ke formulir, dan Anda melakukan hal-hal yang ingin Anda lakukan sebelum kembali (benar), hal-hal ini terjadi sebelum pengiriman yang sebenarnya.

Sebagai contoh:

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

Contoh sederhana

Contoh lain di jquery.com: http://api.jquery.com/submit/#entry-examples

Ron van der Heijden
sumber
2
apakah Anda mengatakan bahwa formulir tidak akan dikirim sampai semua kode sebelum "return true;" pernyataan dieksekusi?
developarvin
2
Ya, itulah fungsi submit () .
Ron van der Heijden
8
Ini bukan contoh yang baik karena itu sinkron. Bagaimana jika hal yang perlu saya lakukan adalah panggilan asinkron? Jadi kasusnya adalah "klik kirim -> lakukan hal asinkron dan jangan kirim formulir -> dalam panggilan balik asinkron mengisi beberapa bidang di formulir -> kirimkan formulir dari panggilan balik"
The Godfather
1
Bagaimana dengan menjalankan beberapa kode jQuery async ?! Akan bekerja juga?
candlejack
ini bagus untuk saya. Saya menggunakannya untuk mengontrol hal-hal sebelum mengirimkan dan jika ada yang tidak benar, saya menggunakan "return false". Saya telah mencari solusi ini selama sehari. Terima kasih banyak.
livefree atau
53

Menggunakan jQuery.one()

Lampirkan penangan ke acara untuk elemen. Penangan dieksekusi paling banyak sekali per elemen per jenis peristiwa

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

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

Penggunaan oneprevent juga infinite loop karena submitperistiwa kustom ini dilepas setelah pengiriman pertama.

Aurel
sumber
2
itu akan dikirimkan setelah mengklik lagi :(
keingintahuan
Mungkin Anda akan menghadapi dengan loop tak terbatas
Mehrdad HosseinNejad
Loop tak terbatas, fungsinya harus .on bukan
.one
26

Saya hanya akan melakukan:

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

Panggil preventDefaultpada awalnya dan gunakan submit()fungsi nanti, jika Anda hanya perlu mengirimkan formulir

bipen
sumber
jangan melibatkan logika di dalam penangan peristiwa klik Anda. mendelegasikannya kepada tanggung jawab orang lain.
Royi Namir
27
Ini mengasumsikan yakin akan mengklik tombol. Bagaimana jika pengguna hanya menekan tombol "masuk" dari dalam formulir? Itu juga akan mengirimkan formulir. Jadi, mungkin bukan ide yang baik untuk mengandalkan tombol kirim agar diklik.
StackOverflowNewbie
saya baru saja memberikan contoh klik ... karena tidak ada kode terkait yang disebutkan pada pertanyaan ....
bipen
2
Bagaimanapun, potongan yang Anda berikan hanya akan berfungsi jika pengguna mengklik tombol. Itu bukanlah cara kerja formulir. Ada saran lain?
StackOverflowNewbie
ikat klik, cegah defaultnya dan picu klik tombol kirim
candlejack
18

Dengan cara ini Anda akan melakukan Loop tanpa akhir di JS Anda. untuk melakukan cara yang lebih baik Anda dapat menggunakan yang berikut ini

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.

Saya harap ini membantu! Terima kasih!

Joepreludian
sumber
cara terbaik sebenarnya, variasi dengan fungsi asinkron - gist.github.com/BjornMelgaard/8ba0ee9d07c20dd8c8b3550c9df3e9ef
srghma
@bjornmelgaard Saya harus ingat bahwa async tidak standar .
Valerio Bozz
6

Ini, IMHO, solusi paling umum dan kuat (jika tindakan Anda dipicu oleh pengguna, misalnya 'pengguna mengklik tombol'):

  • pertama kali penangan dipanggil cek, SIAPA yang memicunya:
    • jika pengguna memicunya - lakukan tugas Anda, lalu picu lagi (jika Anda mau) - secara terprogram
    • jika tidak - tidak melakukan apa-apa (= "lanjutkan default")

Sebagai contoh, perhatikan solusi elegan ini untuk menambahkan "Apakah Anda yakin?" popup ke tombol apa saja hanya dengan mendekorasi tombol dengan atribut. Kami akan melanjutkan perilaku default secara bersyarat jika pengguna tidak memilih keluar.

1. Mari tambahkan ke setiap tombol yang kita ingin teks peringatan "Anda yakin" muncul:

<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. Pasang penangan ke SEMUA tombol seperti itu:

$('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
});

Itu dia.

igorludi
sumber
1
Jawaban yang bagus! Saya tidak tahu bahwa Anda dapat menyampaikan argumen tambahan ke .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
sumber
3

Dengan jQuerydan variasi kecil dari jawaban @ Joepreludian di atas:

Poin penting yang perlu diperhatikan:

  • .one(...) sebagai gantinya .on(...) or .submit(...)
  • namedfungsi alih-alih anonymous functionkarena kita akan merujuknya di dalam 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...
    }
});

Anda dapat mengubah nilai allIsWellvariabel pada cuplikan di bawah ini menjadi trueatau falseuntuk menguji fungsionalitas:

$('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>

Semoga berhasil...

Akash
sumber
2

Dengan cara Javascript murni, Anda dapat mengirimkan formulir setelah mencegah default.

Hal ini karena HTMLFormElement.submit() tidak pernah menyebut itu onSubmit(). Jadi kami mengandalkan keanehan spesifikasi tersebut untuk mengirimkan formulir seolah-olah tidak memiliki penangan kustom pengiriman di sini.

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

Lihat biola ini untuk permintaan sinkron.


Menunggu permintaan asinkron selesai sama mudahnya:

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

Anda dapat melihat biola saya untuk contoh permintaan asinkron.


Dan jika Anda turun dengan janji:

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')
}

Dan inilah yang request .

alairock.dll
sumber
1

Anda dapat menggunakan e.preventDefault()yang akan menghentikan operasi saat ini.

daripada yang bisa Anda lakukan$("#form").submit();

 $('#form').submit(function (e)
{
    return !!e.submit;
});
if(blabla...)
{...
}
else
{
    $('#form').submit(
    {
        submit: true
    });
}
Royi Namir
sumber
ini sangat membingungkan bagiku .. bukankah ini hanya terjadi terus menerus?
dapidmini
1

"Injeksi validasi tanpa mengirimkan perulangan":

Saya hanya ingin memeriksa reCaptcha dan beberapa hal lain sebelum validasi HTML5, jadi saya melakukan sesuatu seperti itu (fungsi validasi mengembalikan true atau false):

$(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
sumber