Bagaimana mencegah tombol mengirimkan formulir

917

Di halaman berikut, dengan Firefox tombol hapus mengirimkan formulir, tetapi tombol tambahkan tidak. Bagaimana cara mencegah tombol hapus mengirimkan formulir?

<html>

<head>
    <script type="text/javascript" src="jquery-1.3.2.min.js"></script>
    <script type="text/javascript">
        function addItem() {
            var v = $('form :hidden:last').attr('name');
            var n = /(.*)input/.exec(v);

            var newPrefix;
            if (n[1].length == 0) {
                newPrefix = '1';
            } else {
                newPrefix = parseInt(n[1]) + 1;
            }

            var oldElem = $('form tr:last');
            var newElem = oldElem.clone(true);
            var lastHidden = $('form :hidden:last');

            lastHidden.val(newPrefix);

            var pat = '=\"' + n[1] + 'input';

            newElem.html(newElem.html().replace(new RegExp(pat, 'g'), '=\"' + newPrefix + 'input'));
            newElem.appendTo('table');
            $('form :hidden:last').val('');
        }

        function removeItem() {
            var rows = $('form tr');
            if (rows.length > 2) {
                rows[rows.length - 1].html('');
                $('form :hidden:last').val('');
            } else {
                alert('Cannot remove any more rows');
            }
        }
    </script>
</head>

<body>
    <form autocomplete="off" method="post" action="">
        <p>Title:<input type="text" /></p>
        <button onclick="addItem(); return false;">Add Item</button>
        <button onclick="removeItem(); return false;">Remove Last Item</button>
        <table>
            <th>Name</th>

            <tr>
                <td><input type="text" id="input1" name="input1" /></td>
                <td><input type="hidden" id="input2" name="input2" /></td>
            </tr>
        </table>
        <input id="submit" type="submit" name="submit" value="Submit">
    </form>
</body>

</html>
Khanpo
sumber
jawaban mana yang Anda rekomendasikan?
sanepete

Jawaban:

1798

Anda menggunakan elemen tombol HTML5. Ingat alasannya adalah tombol ini memiliki perilaku pengiriman default, sebagaimana dinyatakan dalam spesifikasi W3 seperti yang terlihat di sini: Tombol W3C HTML5

Jadi, Anda perlu menentukan jenisnya secara eksplisit:

<button type="button">Button</button>

untuk mengganti jenis pengiriman default. Saya hanya ingin menunjukkan alasan mengapa ini terjadi =)

=)

Metafaniel
sumber
17
Saya juga ingin menunjukkan bahwa elemen HTML memiliki jenis atribut, salah satu jenis yang tombol , tidak harus f # $ 'n memiliki tipe default mengirimkan . Ini benar-benar idiot, dan kesalahan besar dalam spec. Saya menggunakan tombol dalam bentuk sepanjang waktu, dan bahkan jika itu adalah kasus tepi (yang bukan), masih masuk akal untuk memiliki jenis default yang dikirimkan.
dudewad
3
🤯 Saya menghabiskan sebagian besar minggu ini kesal karena aplikasi Elektron saya "disegarkan" ketika saya membuka modal menggunakan tombol dalam formulir. Itu akan terjadi sekali dan kemudian aplikasi berperilaku seperti yang saya harapkan. Saya sama sekali tidak tahu apa yang sedang terjadi. Ini dia! Saya tidak memiliki masalah dengan jenis default yang dikirimkan. Tampaknya sedikit pahit meskipun mengingat saya butuh lima tahun untuk mempelajarinya.
freethebees
4
Berkat referensi Anda, saya baru saja mengetahui bahwa ada type = reset untuk formulir. Luar biasa!
Duong Nguyen
602

Setel jenis pada tombol Anda:

<button type="button" onclick="addItem(); return false;">Add Item</button>
<button type="button" onclick="removeItem(); return false;">Remove Last Item</button>

... yang akan mencegah mereka memicu tindakan kirim saat pengecualian terjadi pada pengendali event. Lalu, perbaiki removeItem()fungsi Anda sehingga tidak memicu pengecualian:

function removeItem() {
  var rows = $('form tr');
  if ( rows.length > 2 ) {
    // change: work on filtered jQuery object
    rows.filter(":last").html('');
    $('form :hidden:last').val('');
  } else {
    alert('Cannot remove any more rows');
  }
}

Perhatikan perubahan: kode asli Anda mengekstraksi elemen HTML dari set jQuery, dan kemudian mencoba memanggil metode jQuery di atasnya - ini melemparkan pengecualian, menghasilkan perilaku default untuk tombol.

FWIW, ada cara lain yang bisa Anda lakukan dengan ini ... Pasang penangan acara Anda menggunakan jQuery, dan gunakan metode preventDefault () pada objek acara jQuery untuk membatalkan perilaku default di muka:

$(function() // execute once the DOM has loaded
{

  // wire up Add Item button click event
  $("#AddItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of add logic
  });

  // wire up Remove Last Item button click event
  $("RemoveLastItem").click(function(event)
  {
    event.preventDefault(); // cancel default behavior

    //... rest of remove last logic
  });

});

...

<button type="button" id="AddItem" name="AddItem">Add Item</button>
<button type="button" id="RemoveLastItem" name="RemoveLastItem">Remove Last Item</button>

Teknik ini menyimpan semua logika Anda di satu tempat, membuatnya lebih mudah untuk di-debug ... itu juga memungkinkan Anda untuk menerapkan back-back dengan mengubah typetombol kembali ke submitdan menangani event server-side - ini dikenal sebagai tidak mengganggu JavaScript .

Shog9
sumber
4
type = "button" tidak selalu berfungsi di Firefox untuk saya. Jika js cukup rumit, dan tetap saja ada kesalahan Firefox akan mengirimkan formulir. Penyakit jiwa!
Matthew Lock
1
@ MatthewLock: Hampir - kesalahan dalam skrip hanya menutup blok kode itu, dan tindakan berlangsung seperti biasa. Coba gunakan metode acara jQuery e.preventDefault () dan / atau e.stopPropgation () sebagai baris pertama dari metode ini. Lihat stackoverflow.com/questions/2017755/… untuk mempelajari lebih lanjut
brichins
8
ketik = tombol seharusnya tidak pernah mengirimkan formulir, tidak peduli apa
Matthew Lock
1
return falsesangat penting. kadang-kadang bahkan menggunakannya untuk tombol kirim ( onclick
Jamie
7
Saya pikir html aneh di sini. Itu harus ketik = "tombol" secara default, tidak mengirimkan. Selalu tak terduga bagi saya untuk melihat pengiriman itu secara default. Itu pengecualian.
Http
31

Beberapa waktu yang lalu saya membutuhkan sesuatu yang sangat mirip ... dan saya mendapatkannya.

Jadi yang saya taruh di sini adalah bagaimana saya melakukan trik agar formulir dapat dikirimkan oleh JavaScript tanpa memvalidasi dan mengeksekusi validasi hanya ketika pengguna menekan tombol (biasanya tombol kirim).

Sebagai contoh saya akan menggunakan formulir minimal, hanya dengan dua bidang dan tombol kirim.

Ingat apa yang diinginkan: Dari JavaScript itu harus dapat dikirimkan tanpa pengecekan. Namun, jika pengguna menekan tombol seperti itu, validasi harus dilakukan dan formulir dikirim hanya jika melewati validasi.

Biasanya semua akan dimulai dari sesuatu di dekat ini (saya menghapus semua hal tambahan tidak penting):

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="submit" value="Send" onclick="JavaScript:return Validator();" />
</form>

Lihat bagaimana tag formulir tidak memiliki onsubmit="..."(ingat itu syarat untuk tidak memilikinya).

Masalahnya adalah bahwa formulir selalu dikirimkan, tidak peduli apakah onclickkembali trueatau false.

Jika saya mengubah type="submit"untuk type="button", tampaknya bekerja tetapi tidak. Tidak pernah mengirimkan formulir, tetapi itu bisa dilakukan dengan mudah.

Jadi akhirnya saya menggunakan ini:

<form method="post" id="theFormID" name="theFormID" action="">
   <input type="text" id="Field1" name="Field1" />
   <input type="text" id="Field2" name="Field2" />
   <input type="button" value="Send" onclick="JavaScript:return Validator();" />
</form>

Dan function Validator, di mana return True;, saya juga menambahkan kalimat pengiriman JavaScript, sesuatu yang mirip dengan ini:

function Validator(){
   //  ...bla bla bla... the checks
   if(                              ){
      document.getElementById('theFormID').submit();
      return(true);
   }else{
      return(false);
   }
}

Ini id=""hanya untuk JavaScript getElementById, name=""itu hanya untuk itu muncul pada data POST.

Cara seperti itu berfungsi seperti yang saya butuhkan.

Saya menempatkan ini hanya untuk orang-orang yang tidak memerlukan onsubmitfungsi pada formulir, tetapi membuat beberapa validasi ketika tombol ditekan oleh pengguna.

Mengapa saya tidak perlu mengirimkan pada tag formulir? Mudah, pada bagian JavaScript lain saya perlu melakukan pengiriman tetapi saya tidak ingin ada validasi.

Alasannya: Jika pengguna adalah orang yang melakukan pengiriman, saya ingin dan perlu validasi untuk dilakukan, tetapi jika itu JavaScript, kadang-kadang saya perlu melakukan pengiriman sementara validasi seperti itu akan menghindarinya.

Ini mungkin terdengar aneh, tetapi tidak ketika berpikir misalnya: pada Login ... dengan beberapa batasan ... seperti tidak diizinkan untuk menggunakan sesi PHP dan cookie tidak diizinkan!

Jadi, tautan apa pun harus dikonversi ke formulir yang dikirimkan, sehingga data masuk tidak hilang. Ketika belum ada login, itu juga harus berfungsi. Jadi tidak ada validasi yang harus dilakukan pada tautan. Tapi saya ingin menyajikan pesan kepada pengguna jika pengguna belum memasukkan kedua bidang, pengguna dan pass. Jadi, jika ada yang hilang, formulir itu tidak boleh dikirim! ada masalahnya.

Lihat masalahnya: formulir tidak boleh dikirim ketika satu bidang kosong hanya jika pengguna telah menekan tombol, jika itu adalah kode JavaScript, ia harus dapat dikirim.

Jika saya melakukan pekerjaan pada onsubmittag formulir, saya perlu tahu apakah itu pengguna atau JavaScript lainnya. Karena tidak ada parameter yang dapat dilewati, itu tidak mungkin secara langsung, sehingga beberapa orang menambahkan variabel untuk mengetahui apakah validasi harus dilakukan atau tidak. Hal pertama pada fungsi validasi adalah memeriksa nilai variabel itu, dll ... Terlalu rumit dan kode tidak mengatakan apa yang benar-benar diinginkan.

Jadi solusinya adalah tidak memiliki onsubmit pada tag form. Insead meletakkannya di tempat yang benar-benar dibutuhkan, di tombol.

Untuk sisi lain, mengapa meletakkan kode onsubmit karena secara konsep saya tidak ingin validasi onsubmit. Saya sangat ingin validasi tombol.

Tidak hanya kode lebih jelas, itu adalah di mana harus. Hanya ingat ini: - Saya tidak ingin JavaScript memvalidasi formulir (yang harus selalu dilakukan oleh PHP di sisi server) - Saya ingin menunjukkan kepada pengguna pesan yang mengatakan semua bidang tidak boleh kosong, yang membutuhkan JavaScript (klien sisi)

Jadi mengapa sebagian orang (berpikir atau memberi tahu saya) itu harus dilakukan dengan validasi onsumbit? Tidak, secara konseptual saya tidak melakukan onsumbit memvalidasi di sisi klien. Saya hanya melakukan sesuatu pada tombol ditekan, jadi mengapa tidak membiarkan itu diterapkan?

Baik kode dan gaya melakukan trik dengan sempurna. Pada JavaScript apa pun yang saya perlukan untuk mengirim formulir yang baru saja saya masukkan:

document.getElementById('theFormID').action='./GoToThisPage.php'; // Where to go
document.getElementById('theFormID').submit(); // Send POST data and go there

Dan itu melompati validasi ketika saya tidak membutuhkannya. Itu hanya mengirim formulir dan memuat halaman yang berbeda, dll.

Tetapi jika pengguna mengklik tombol kirim (alias type="button"tidak type="submit") validasi dilakukan sebelum membiarkan formulir dikirimkan dan jika tidak valid tidak dikirim.

Semoga ini membantu orang lain untuk tidak mencoba kode yang panjang dan rumit. Hanya tidak digunakan onsubmitjika tidak diperlukan, dan gunakan onclick. Tapi ingat untuk mengubah type="submit"ke type="button"dan jangan lupa untuk melakukan submit()oleh JavaScript.

z666zz666z
sumber
28

Saya setuju dengan Shog9, meskipun saya mungkin menggunakan:

<input type = "button" onClick="addItem(); return false;" value="Add Item" />

Menurut w3schools , <button>tag memiliki perilaku berbeda di browser yang berbeda.

poundifdef
sumber
18

Misalkan form HTML Anda sudah id="form_id"

<form id="form_id">
<!--your HTML code-->
</form>

Tambahkan potongan jQuery ini ke kode Anda untuk melihat hasilnya,

$("#form_id").submit(function(){
  return false;
});
Prateek Joshi
sumber
18

Anda cukup mendapatkan referensi tombol Anda menggunakan jQuery, dan mencegah penyebarannya seperti di bawah ini:

 $(document).ready(function () {
    $('#BUTTON_ID').click(function(e) {

            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();

            return false;
    });});
Ata Iravani
sumber
2
e.preventDefault(); e.stopPropagation();sudah cukup untuk bekerja. e.stopImmediatePropagation()ini menimbulkan kesalahan pada metode yang tidak terdefinisi di Chrome.
Subroto
14

$("form").submit(function () { return false; }); yang akan mencegah tombol mengirimkan atau Anda hanya dapat mengubah jenis tombol menjadi "tombol" <input type="button"/>daripada <input type="submit"/> Yang hanya akan berfungsi jika tombol ini bukan satu-satunya tombol dalam formulir ini.

Shiala
sumber
2
Ini untuk jQuery, yang setara dengan Javascript adalah: myform.onsubmit = function () {return false} ... juga, bahkan jika Anda menghapus tombol kirim, formulir juga bisa dikirimkan dengan menekan enter dari bidang formulir lain.
Synexis
10

Ini adalah kesalahan html5 seperti yang telah dikatakan, Anda masih dapat memiliki tombol sebagai kirim (jika Anda ingin mencakup pengguna javascript dan non javascript) menggunakannya seperti:

     <button type="submit" onclick="return false"> Register </button>

Dengan cara ini Anda akan membatalkan pengiriman tetapi masih melakukan apa pun yang Anda lakukan dalam fungsi jquery atau javascript dan melakukan pengiriman untuk pengguna yang tidak memiliki javascript.

sagit
sumber
8

Saya yakin bahwa pada FF

removeItem 

fungsi menemukan kesalahan JavaScript, ini tidak terjadi di IE

Ketika kesalahan javascript muncul, kode "return false" tidak akan berjalan, membuat halaman menjadi postback

Alin Vasile
sumber
8

Return salah mencegah perilaku default. tetapi return false memecah gelembung acara klik tambahan. Ini berarti jika ada binding klik lain setelah fungsi ini dipanggil, yang lain tidak mempertimbangkan.

 <button id="btnSubmit" type="button">PostData</button>
 <Script> $("#btnSubmit").click(function(){
   // do stuff
   return false;
}); </Script>

Atau cukup Anda dapat menempatkan seperti ini

 <button type="submit" onclick="return false"> PostData</button>
Sunil Dhappadhule
sumber
7

Cukup tambahkan e.preventDefault();metode Anda agar halaman Anda tidak mengirimkan formulir.

function myFunc(e){
       e.preventDefault();
}

Menurut MDN Web Documents

Metode preventDefault () pada antarmuka Acara memberi tahu agen pengguna bahwa jika acara tidak diproses secara eksplisit, tindakan defaultnya tidak boleh diperhitungkan seperti biasanya. Acara terus menyebar seperti biasa, kecuali salah satu pendengarnya memanggil stopPropagation ()atau stopImmediatePropagation (), yang mana salah satu menghentikan propagasi.

Mselmi Ali
sumber
6

Atur tombol Anda dengan cara normal dan gunakan event.preventDefault seperti ..

   <button onclick="myFunc(e)"> Remove </button>  
   ...
   ...

   In function...

   function myFunc(e){
       e.preventDefault();
   }
Vishal
sumber
4
return false;

Anda dapat mengembalikan false di akhir fungsi atau setelah panggilan fungsi.

Selama itu adalah hal terakhir yang terjadi, formulir tidak akan dikirimkan.

WonderWorker
sumber
2

Inilah pendekatan sederhana:

$('.mybutton').click(function(){

    /* Perform some button action ... */
    alert("I don't like it when you press my button!");

    /* Then, the most important part ... */
    return false;

});
aksioma82
sumber
1

Kode contoh berikut menunjukkan kepada Anda bagaimana mencegah klik tombol dari mengirimkan formulir.

Anda dapat mencoba kode sampel saya:

 <form autocomplete="off" method="post" action="">
   <p>Title:
     <input type="text" />
   </p>
   <input type="button" onclick="addItem()" value="Add Item">
   <input type="button" onclick="removeItem()" value="Remove Last Item">
   <table>
     <th>Name</th>

     <tr>
       <td>
         <input type="text" id="input1" name="input1" />
       </td>
       <td>
         <input type="hidden" id="input2" name="input2" />
       </td>
     </tr>
   </table>
   <input id="submit" type="submit" name="submit" value="Submit">
 </form>
<script language="javascript">
function addItem() {
return false;
}

function removeItem() {
return false;
}
</script>
KNVB
sumber
0

Saya tidak dapat menguji ini sekarang, tapi saya pikir Anda bisa menggunakan metode preventDefault jQuery .

Tyler Rash
sumber
0

Fungsi removeItem sebenarnya mengandung kesalahan, yang membuat tombol form melakukan perilaku defaultnya (mengirimkan formulir). Konsol kesalahan javascript biasanya akan memberikan pointer dalam kasus ini.

Lihat fungsi removeItem di bagian javascript:

Garis:

rows[rows.length-1].html('');

tidak bekerja Coba ini sebagai gantinya:

rows.eq(rows.length-1).html('');
Ylebre
sumber