วิธีป้องกันปุ่มจากการส่งแบบฟอร์ม


917

ในหน้าต่อไปด้วย Firefox ปุ่มลบจะส่งแบบฟอร์ม แต่ปุ่มเพิ่มจะไม่ส่ง ฉันจะป้องกันปุ่มลบจากการส่งแบบฟอร์มได้อย่างไร

<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>

คุณแนะนำคำตอบอะไร?
sanepete

คำตอบ:


1797

คุณกำลังใช้องค์ประกอบปุ่ม HTML5 จำสาเหตุที่ปุ่มนี้มีพฤติกรรมเริ่มต้นของการส่งตามที่ระบุไว้ในข้อกำหนด W3 ตามที่เห็นที่นี่: ปุ่ม W3C HTML5

ดังนั้นคุณต้องระบุประเภทของมันอย่างชัดเจน:

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

เพื่อแทนที่ประเภทการส่งเริ่มต้น ฉันแค่ต้องการชี้ให้เห็นว่าทำไมสิ่งนี้จึงเกิดขึ้น =)

=)


17
ฉันยังต้องการที่จะชี้ให้เห็นว่าองค์ประกอบ HTML ที่มีประเภทแอตทริบิวต์ซึ่งเป็นหนึ่งในประเภทของซึ่งเป็นปุ่มไม่ควรฉ # $ n 'มีชนิดเริ่มต้นของการส่ง มันเป็นแค่งี่เง่าธรรมดาและความผิดพลาดอย่างมากในสเป็ค ฉันใช้ปุ่มในรูปแบบตลอดเวลาและแม้ว่ามันจะเป็นกรณีขอบ (ซึ่งไม่ใช่) มันก็ยังคงมีเหตุผลที่จะต้องส่งประเภทเริ่มต้น
dudewad

3
🤯ฉันใช้เวลาส่วนใหญ่ในสัปดาห์นี้ทำให้รำคาญว่าแอปอิเล็กตรอนของฉัน "รีเฟรช" เมื่อฉันเปิด modal โดยใช้ปุ่มภายในฟอร์ม มันจะเกิดขึ้นเพียงครั้งเดียวแล้วแอพก็ทำงานตามที่คาดไว้ ฉันไม่รู้เลยว่าเกิดอะไรขึ้น นี่มัน! ฉันไม่มีปัญหากับประเภทเริ่มต้นที่จะส่ง ดูเหมือน gotcha สักหน่อยถึงแม้ว่าจะใช้เวลาห้าปีในการเรียนรู้เกี่ยวกับมัน
Freethebees

4
ขอบคุณที่อ้างอิงของคุณฉันเพิ่งรู้ว่ามี type = reset สำหรับแบบฟอร์ม ! น่ากลัว
Duong Nguyen

602

ตั้งค่าประเภทที่ปุ่มของคุณ:

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

... ที่จะป้องกันไม่ให้มีการทริกเกอร์การส่งเมื่อเกิดข้อยกเว้นในตัวจัดการเหตุการณ์ จากนั้นแก้ไขremoveItem()ฟังก์ชันของคุณเพื่อไม่ให้เกิดข้อยกเว้น:

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

สังเกตการเปลี่ยนแปลง: รหัสต้นฉบับของคุณแยกองค์ประกอบ HTML จากชุด jQuery แล้วลองเรียกวิธีการ jQuery ที่มันทำให้เกิดข้อยกเว้นทำให้เกิดพฤติกรรมเริ่มต้นสำหรับปุ่ม

FWIW ยังมีอีกวิธีที่คุณสามารถทำได้ด้วย ... วางสายตัวจัดการเหตุการณ์ของคุณโดยใช้ jQuery และใช้เมธอดPreventDefault ()บนวัตถุเหตุการณ์ของ jQuery เพื่อยกเลิกพฤติกรรมเริ่มต้นล่วงหน้า:

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

เทคนิคนี้ช่วยให้ตรรกะทั้งหมดของคุณอยู่ในที่เดียวทำให้ง่ายต่อการดีบัก ... นอกจากนี้ยังช่วยให้คุณสามารถนำไปใช้โดยการเปลี่ยนtypeปุ่มกลับไปที่submitและจัดการกับฝั่งเซิร์ฟเวอร์เหตุการณ์ - ซึ่งเป็นที่รู้จักกันว่าเป็นการสร้างความรำคาญ JavaScript


4
type = "button" อาจไม่ทำงานใน Firefox สำหรับฉันเสมอไป หาก js ซับซ้อนเพียงพอและมีข้อผิดพลาด Firefox จะส่งแบบฟอร์มต่อไป บ้า!
แมทธิวล็อค

1
@MatthewLock: แทบจะ - ข้อผิดพลาดในสคริปต์เพิ่งปิดบล็อกรหัสนั้นและการดำเนินการดำเนินการตามปกติ ลองเรียกใช้วิธีการเหตุการณ์ jQuery e.preventDefault () และ / หรือ e.stopPropgation () เป็นบรรทัดแรกของวิธีการ ดูstackoverflow.com/questions/2017755/…เพื่อเรียนรู้เพิ่มเติม
brichins

8
ปุ่ม type = ไม่ควรส่งแบบฟอร์มไม่ว่าจะเกิดอะไรขึ้น
Matthew Lock

1
return falseมีความสำคัญมาก บางครั้งใช้เพื่อส่งปุ่ม ( onclick
Jamie

7
ฉันคิดว่า html นั้นแปลกที่นี่ ควรเป็น type = "button" โดยค่าเริ่มต้นไม่ใช่กำลังส่ง ฉันคาดไม่ถึงเสมอที่จะเห็นว่าการส่งนั้นเป็นค่าเริ่มต้น มันเป็นข้อยกเว้น
httpete

31

บางครั้งฉันต้องการสิ่งที่คล้ายกันมาก ... และฉันได้รับมัน

ดังนั้นสิ่งที่ฉันใส่ที่นี่คือวิธีที่ฉันทำเทคนิคเพื่อให้สามารถส่งฟอร์มโดย JavaScript โดยไม่ต้องมีการตรวจสอบและดำเนินการตรวจสอบความถูกต้องเฉพาะเมื่อผู้ใช้กดปุ่ม (โดยทั่วไปคือปุ่มส่ง)

ตัวอย่างเช่นฉันจะใช้รูปแบบที่น้อยที่สุดมีเพียงสองฟิลด์และปุ่มส่ง

จำสิ่งที่ต้องการ: จาก JavaScript จะต้องสามารถส่งได้โดยไม่ต้องตรวจสอบใด ๆ อย่างไรก็ตามหากผู้ใช้กดปุ่มดังกล่าวการตรวจสอบจะต้องทำและส่งแบบฟอร์มเฉพาะเมื่อผ่านการตรวจสอบ

โดยปกติทุกอย่างจะเริ่มจากบางสิ่งที่อยู่ใกล้สิ่งนี้ (ฉันลบสิ่งพิเศษทั้งหมดที่ไม่สำคัญ):

<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>

ดูว่าฟอร์มแท็กไม่มีonsubmit="..."(จำได้ว่ามันเป็นเงื่อนไขที่ไม่ได้มี)

ปัญหาคือว่าการส่งแบบฟอร์มเสมอไม่ว่าถ้าonclickผลตอบแทนหรือtruefalse

ถ้าฉันเปลี่ยนtype="submit"สำหรับtype="button"ดูเหมือนว่าจะทำงาน แต่ไม่ได้ มันไม่เคยส่งแบบฟอร์ม แต่สามารถทำได้ง่าย

ดังนั้นในที่สุดฉันก็ใช้สิ่งนี้:

<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>

และในfunction Validatorกรณีที่return True;ฉันยังเพิ่ม JavaScript ส่งประโยคสิ่งที่คล้ายกับนี้:

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

id=""เป็นเพียงสำหรับจาวาสคริปต์getElementByIdที่name=""เป็นเพียงเพื่อให้ปรากฏในข้อมูล POST

ในวิธีดังกล่าวทำงานได้ตามที่ฉันต้องการ

ฉันใส่สิ่งนี้ไว้สำหรับคนที่ไม่ต้องการonsubmitฟังก์ชั่นในแบบฟอร์ม แต่ทำการตรวจสอบความถูกต้องบางอย่างเมื่อมีการกดปุ่มโดยผู้ใช้

ทำไมฉันไม่ต้องการส่งแบบฟอร์มแท็ก? ง่ายต่อส่วน JavaScript อื่น ๆ ฉันต้องทำการส่ง แต่ฉันไม่ต้องการให้มีการตรวจสอบใด ๆ

เหตุผล: หากผู้ใช้เป็นผู้ดำเนินการส่งฉันต้องการและต้องการการตรวจสอบที่จะทำ แต่ถ้ามันเป็น JavaScript บางครั้งฉันจำเป็นต้องดำเนินการส่งในขณะที่การตรวจสอบดังกล่าวจะหลีกเลี่ยงได้

อาจฟังดูแปลก แต่ไม่ใช่เมื่อคิดถึงตัวอย่าง: ในการเข้าสู่ระบบ ... โดยมีข้อ จำกัด บางอย่าง ... ไม่อนุญาตให้ใช้เซสชัน PHP และไม่อนุญาตให้ใช้คุกกี้!

ดังนั้นลิงก์ใด ๆ จะต้องถูกแปลงเป็นส่งแบบฟอร์มดังกล่าวดังนั้นข้อมูลการเข้าสู่ระบบจะไม่สูญหาย เมื่อยังไม่มีการลงชื่อเข้าใช้จะต้องใช้งาน ดังนั้นจึงไม่จำเป็นต้องมีการตรวจสอบความถูกต้องของลิงก์ แต่ฉันต้องการนำเสนอข้อความให้กับผู้ใช้หากผู้ใช้ไม่ได้ป้อนทั้งฟิลด์ผู้ใช้และรหัสผ่าน ดังนั้นหากขาดหายไปจะต้องไม่ส่งแบบฟอร์ม! มีปัญหา

ดูปัญหา: ไม่ต้องส่งแบบฟอร์มเมื่อช่องว่างหนึ่งช่องว่างหากผู้ใช้กดปุ่มหากเป็นรหัส JavaScript จะต้องสามารถส่งได้

หากฉันทำงานบนonsubmitแท็กฟอร์มฉันจะต้องรู้ว่าเป็นผู้ใช้หรือ JavaScript อื่น ๆ เนื่องจากไม่มีพารามิเตอร์ที่สามารถส่งผ่านได้จึงไม่สามารถทำได้โดยตรงดังนั้นบางคนจึงเพิ่มตัวแปรเพื่อบอกว่าต้องทำการตรวจสอบความถูกต้องหรือไม่ สิ่งแรกในฟังก์ชั่นการตรวจสอบความถูกต้องคือการตรวจสอบค่าตัวแปร ฯลฯ ... ซับซ้อนเกินไปและรหัสไม่ได้บอกสิ่งที่ต้องการจริงๆ

ดังนั้นการแก้ปัญหาคือไม่ต้องส่งบนแท็กฟอร์ม Insead วางไว้ตรงจุดที่จำเป็นจริงๆ

สำหรับอีกด้านหนึ่งทำไมใส่ onsubmit code เนื่องจาก conceptually ฉันไม่ต้องการ onsubmit validation ฉันต้องการการตรวจสอบปุ่มจริง ๆ

ไม่เพียง แต่รหัสจะชัดเจนยิ่งขึ้น แต่ยังเป็นที่ที่ต้องเป็น เพียงจำไว้ว่า: - ฉันไม่ต้องการให้ JavaScript ตรวจสอบความถูกต้องของรูปแบบ (ซึ่งจะต้องทำโดย PHP ที่ฝั่งเซิร์ฟเวอร์เสมอ) - ฉันต้องการแสดงข้อความที่บอกให้ผู้ใช้ทุกคนเห็นว่าฟิลด์ทั้งหมดต้องไม่ว่างเปล่า ข้าง)

ดังนั้นทำไมบางคน (คิดหรือบอกฉัน) จะต้องทำในการตรวจสอบ onsumbit? ไม่ฉันไม่ได้ทำการตรวจสอบความถูกต้องที่แนวคิด ฉันแค่กดปุ่มทำอะไรสักอย่างแล้วทำไมไม่ปล่อยให้มันทำ?

ด้วยรหัสและรูปแบบที่หลอกลวงได้อย่างสมบูรณ์แบบ ใน JavaScript ใด ๆ ที่ฉันต้องการส่งแบบฟอร์มที่ฉันใส่:

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

และนั่นเป็นการข้ามการตรวจสอบเมื่อฉันไม่ต้องการ มันแค่ส่งแบบฟอร์มและโหลดหน้าอื่น ๆ

แต่ถ้าผู้ใช้คลิกปุ่มส่ง (aka type="button"ไม่type="submit") การตรวจสอบจะทำก่อนที่จะให้ส่งแบบฟอร์มและถ้าไม่ถูกต้องไม่ได้ส่ง

หวังว่านี่จะช่วยให้ผู้อื่นไม่ลองใช้รหัสที่ยาวและซับซ้อน เพียงแค่ไม่ใช้ถ้าไม่จำเป็นต้องและการใช้งานonsubmit onclickแต่อย่าลืมเปลี่ยนtype="submit"ไปใช้type="button"อย่าลืมsubmit()จาวาสคริปต์ด้วย


28

ฉันเห็นด้วยกับ Shog9 แต่ฉันอาจใช้แทน:

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

ตามที่ w3schoolsที่<button>แท็กมีพฤติกรรมที่แตกต่างกันในเบราว์เซอร์ที่แตกต่างกัน


18

สมมติว่ารูปแบบ HTML ของคุณมี id="form_id"

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

เพิ่มตัวอย่าง jQuery นี้ไปยังรหัสของคุณเพื่อดูผลลัพธ์

$("#form_id").submit(function(){
  return false;
});

18

คุณสามารถรับการอ้างอิงของปุ่มของคุณโดยใช้ jQuery และป้องกันการแพร่กระจายของมันดังด้านล่าง:

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

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

            return false;
    });});

2
e.preventDefault(); e.stopPropagation();เพียงพอสำหรับสิ่งที่จะทำงาน e.stopImmediatePropagation()นี่เป็นการพ่นข้อผิดพลาดของวิธีที่ไม่ได้กำหนดใน Chrome
Subroto

14

$("form").submit(function () { return false; }); ที่จะป้องกันไม่ให้ปุ่มจากการส่งหรือคุณก็สามารถเปลี่ยนชนิดปุ่ม "ปุ่ม" <input type="button"/>แทน<input type="submit"/> ซึ่งจะทำงานเฉพาะในกรณีที่ปุ่มนี้ไม่ได้เป็นเพียงปุ่มเดียวในรูปแบบนี้


2
สิ่งนี้มีไว้สำหรับ jQuery ซึ่งเทียบเท่าใน Javascript คือ: myform.onsubmit = function () {return false} ... เช่นกันแม้ว่าคุณจะลบปุ่มส่ง แต่ก็สามารถส่งแบบฟอร์มได้โดยการกด enter จากฟิลด์ฟอร์มอื่น
Synexis

10

นี่เป็นข้อผิดพลาด html5 อย่างที่กล่าวไว้คุณยังสามารถมีปุ่มเป็นส่งได้ (หากคุณต้องการให้ครอบคลุมทั้งผู้ใช้ javascript และไม่ใช่ javascript) โดยใช้:

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

วิธีนี้คุณจะยกเลิกการส่ง แต่ยังคงทำสิ่งที่คุณทำใน jquery หรือฟังก์ชัน javascript และทำส่งสำหรับผู้ใช้ที่ไม่มี javascript


8

ฉันแน่ใจว่าใน FF

removeItem 

ฟังก์ชั่นพบข้อผิดพลาด JavaScript นี้ไม่ได้เกิดขึ้นบน IE

เมื่อข้อผิดพลาด javascript ปรากฏขึ้นรหัส "return false" จะไม่ทำงานทำให้หน้านั้นเปลี่ยนไป


8

return false ป้องกันพฤติกรรมเริ่มต้น แต่ผลตอบแทนที่ผิดพลาดจะทำให้การคลิกเหตุการณ์เพิ่มเติมไม่น่าพอใจ ซึ่งหมายความว่าหากมีการผูกคลิกอื่น ๆ หลังจากเรียกใช้ฟังก์ชันนี้แล้วคนอื่น ๆ จะไม่พิจารณา

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

หรือเพียงแค่ใส่แบบนี้

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

7

เพียงเพิ่มe.preventDefault();วิธีการของคุณควรป้องกันไม่ให้หน้าของคุณส่งแบบฟอร์ม

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

ตามเอกสาร MDN Web

เมธอด PreventDefault () ของส่วนต่อประสานเหตุการณ์จะบอกตัวแทนผู้ใช้ว่าหากเหตุการณ์ไม่ได้ถูกประมวลผลอย่างชัดเจนการกระทำเริ่มต้นของมันไม่ควรนำมาพิจารณาเช่นเดียวกับปกติ เหตุการณ์ยังคงเผยแพร่ตามปกติเว้นแต่ผู้ฟังคนใดคนหนึ่งโทรstopPropagation ()หรือstopImmediatePropagation ()อย่างใดอย่างหนึ่งซึ่งยุติการเผยแพร่


6

ตั้งค่าปุ่มของคุณตามปกติและใช้ event.preventDefault เช่น ..

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

   In function...

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

4
return false;

คุณสามารถคืนค่าเท็จเมื่อสิ้นสุดฟังก์ชันหรือหลังจากการเรียกใช้ฟังก์ชัน

ตราบใดที่มันเป็นสิ่งสุดท้ายที่เกิดขึ้นแบบฟอร์มจะไม่ส่ง


2

นี่เป็นวิธีง่ายๆ:

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

});

1

โค้ดตัวอย่างต่อไปนี้แสดงวิธีป้องกันการคลิกปุ่มจากการส่งแบบฟอร์ม

คุณอาจลองรหัสตัวอย่างของฉัน:

 <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>


0

ฟังก์ชั่น removeItem มีข้อผิดพลาดจริงซึ่งทำให้ปุ่มรูปแบบมันเป็นพฤติกรรมเริ่มต้น (ส่งแบบฟอร์ม) คอนโซลข้อผิดพลาดจาวาสคริปต์มักจะให้ตัวชี้ในกรณีนี้

ลองใช้ฟังก์ชั่น removeItem ในส่วนของ javascript:

เส้น:

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

ไม่ทำงาน ลองใช้สิ่งนี้แทน:

rows.eq(rows.length-1).html('');
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.