jQuery - ป้องกันค่าเริ่มต้นจากนั้นดำเนินการต่อตามค่าเริ่มต้น


105

ฉันมีแบบฟอร์มที่เมื่อส่งแล้วฉันต้องดำเนินการเพิ่มเติมบางอย่างก่อนจึงจะส่งแบบฟอร์มได้ ฉันสามารถป้องกันพฤติกรรมการส่งแบบฟอร์มเริ่มต้นจากนั้นทำการประมวลผลเพิ่มเติมของฉัน (โดยทั่วไปเรียกว่า Google Maps API และเพิ่มฟิลด์ที่ซ่อนอยู่สองสามฟิลด์ลงในแบบฟอร์ม) จากนั้นฉันต้องใช้แบบฟอร์มเพื่อส่ง

มีวิธี "ป้องกันค่าเริ่มต้น" หรือไม่จากนั้นจึง "ใช้ค่าเริ่มต้นต่อไป"


@FelixKling คุณหมายถึงstackoverflow.com/questions/7610871/…หรือเปล่า?
M. Mimpen

คำตอบ:


53

เมื่อคุณผูก.submit()เหตุการณ์กับแบบฟอร์มและคุณทำสิ่งที่คุณต้องการทำก่อนที่จะกลับมา (จริง) สิ่งเหล่านี้จะเกิดขึ้นก่อนการส่งจริง

ตัวอย่างเช่น:

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

ตัวอย่างง่ายๆ

อีกตัวอย่างหนึ่งใน jquery.com: http://api.jquery.com/submit/#entry-examples


2
คุณกำลังบอกว่าแบบฟอร์มจะไม่ส่งจนกว่ารหัสทั้งหมดก่อนที่จะ "return true;" คำสั่งถูกดำเนินการ?
developmentarvin

2
ใช่นั่นคือสิ่งที่ฟังก์ชันsubmit ()ทำ
Ron van der Heijden

8
ไม่ใช่ตัวอย่างที่ดีเพราะมันซิงโครไนซ์ จะเกิดอะไรขึ้นถ้าสิ่งที่ฉันต้องทำคือ async call? ดังนั้นกรณีนี้คือ "click submit -> do async stuff และอย่า" ส่งแบบฟอร์ม -> ใน async callback ให้กรอกข้อมูลบางช่องในแบบฟอร์ม -> ส่งแบบฟอร์มจากการติดต่อกลับ "
The Godfather

1
แล้วรันโค้ด async jQuery บ้างล่ะ! จะทำงานด้วยหรือไม่
candlejack

มันใช้งานได้ดีสำหรับฉัน ฉันใช้มันเพื่อควบคุมสิ่งต่างๆก่อนที่จะส่งและหากสิ่งต่างๆไม่ถูกต้องฉันก็ใช้ "return false" ฉันมองหาวิธีแก้ปัญหานี้มาหนึ่งวันแล้ว ขอบคุณมาก.
livefreeor

53

ใช้ jQuery.one()

แนบตัวจัดการกับเหตุการณ์สำหรับองค์ประกอบ ตัวจัดการจะดำเนินการมากที่สุดหนึ่งครั้งต่อองค์ประกอบต่อประเภทเหตุการณ์

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

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

การใช้การoneป้องกันการวนซ้ำแบบไม่มีที่สิ้นสุดเนื่องจากsubmitเหตุการณ์ที่กำหนดเองนี้ถูกถอดออกหลังจากการส่งครั้งแรก


2
จะส่งหลังจากคลิกอีกครั้ง :(
อยากรู้อยากเห็น

2
คุณอาจจะเผชิญกับลูปที่ไม่มีที่สิ้นสุด
Mehrdad HosseinNejad

ลูปไม่มีที่สิ้นสุดฟังก์ชันควรเป็น. ไม่ใช่.
one

ในการป้องกันการวนซ้ำแบบไม่มีที่สิ้นสุดให้เลิกผูกเหตุการณ์แบบฟอร์มก่อนแล้วส่ง $(this).unbind(); $(this).submit();
Robby Alvian Jaya Mulia

26

ฉันจะทำ:

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

โทร preventDefaultในตอนแรกและใช้submit()ฟังก์ชันในภายหลังหากคุณต้องการส่งแบบฟอร์ม


อย่าเกี่ยวข้องกับตรรกะภายในตัวจัดการเหตุการณ์คลิกของคุณ มอบหมายให้ผู้อื่นรับผิดชอบ
Royi Namir

27
นี่จะถือว่าแน่ใจว่าจะคลิกปุ่ม จะเป็นอย่างไรหากผู้ใช้กดปุ่ม "Enter" จากในแบบฟอร์ม ที่จะส่งแบบฟอร์ม ดังนั้นจึงไม่ควรพึ่งพาการคลิกปุ่มส่ง
StackOverflowNewbie

ฉันแค่ยกตัวอย่างการคลิก ... เนื่องจากไม่มีรหัสที่เกี่ยวข้องที่กล่าวถึงในคำถามนี้ ....
bipen

2
ไม่ว่าในกรณีใดตัวอย่างข้อมูลที่คุณให้จะใช้ได้เฉพาะเมื่อผู้ใช้คลิกปุ่ม นั่นไม่ใช่วิธีการทำงานของแบบฟอร์ม ข้อเสนอแนะอื่น ๆ ?
StackOverflowNewbie

ผูกการคลิกป้องกันค่าเริ่มต้นและเริ่มการคลิกปุ่มส่ง
candlejack

18

ใช้วิธีนี้คุณจะทำ Loop ที่ไม่มีที่สิ้นสุดบน JS ของคุณ วิธีที่ดีกว่าคุณสามารถใช้สิ่งต่อไปนี้

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.

ฉันหวังว่ามันจะช่วยได้! ขอบคุณ!


วิธีที่ดีที่สุดจริงๆแล้วการเปลี่ยนแปลงด้วยฟังก์ชัน async - gist.github.com/BjornMelgaard/8ba0ee9d07c20dd8c8b3550c9df3e9ef
srghma

@bjornmelgaard ฉันต้องจำไว้ว่า async คือไม่ได้มาตรฐาน
Valerio Bozz

6

นี่คือ IMHO ซึ่งเป็นโซลูชันทั่วไปและมีประสิทธิภาพมากที่สุด (หากการกระทำของคุณถูกกระตุ้นโดยผู้ใช้เช่น 'ผู้ใช้คลิกที่ปุ่ม'):

  • ครั้งแรกที่มีการเรียกตัวจัดการว่า WHO เรียกใช้:
    • หากผู้ใช้ขโมยข้อมูล - ทำสิ่งต่างๆของคุณแล้วเรียกใช้อีกครั้ง (ถ้าคุณต้องการ) - โดยทางโปรแกรม
    • มิฉะนั้น - ไม่ต้องทำอะไรเลย (= "เริ่มต้นต่อไป")

ตัวอย่างเช่นสังเกตโซลูชันที่สวยงามนี้ในการเพิ่ม "แน่ใจหรือไม่" ป๊อปอัปไปยังปุ่มใดก็ได้เพียงแค่ตกแต่งปุ่มด้วยแอตทริบิวต์ เราจะดำเนินการตามเงื่อนไขเริ่มต้นต่อไปหากผู้ใช้ไม่เลือกไม่ใช้

1. มาเพิ่มทุกปุ่มที่เราต้องการให้ "คุณแน่ใจ" ป๊อปอัพข้อความเตือน:

<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. แนบตัวจัดการกับปุ่มดังกล่าวทั้งหมด:

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

แค่นั้นแหละ.


1
ตอบโจทย์มาก! ฉันไม่รู้ว่าคุณสามารถส่งอาร์กิวเมนต์พิเศษไปที่ .trigger ()
James Hibbard

6
$('#myform').on('submit',function(event){
  // block form submit event
  event.preventDefault();

  // Do some stuff here
  ...

  // Continue the form submit
  event.currentTarget.submit();
});

2

ด้วยวิธี Javascript คุณสามารถส่งแบบฟอร์มหลังจากป้องกันค่าเริ่มต้น

เนื่องจากHTMLFormElement.submit() ไม่เคยเรียกไฟล์onSubmit(). ดังนั้นเราจึงอาศัยความแปลกของข้อกำหนดนั้นในการส่งแบบฟอร์มราวกับว่าไม่มีตัวจัดการการส่งข้อมูลที่กำหนดเองที่นี่

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

ดูซอนี้สำหรับคำร้องขอแบบซิงโครนัส


การรอให้คำขอ async เสร็จสิ้นนั้นง่ายมาก:

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

คุณสามารถตรวจสอบซอของฉันสำหรับตัวอย่างคำขอแบบอะซิงโครนัส


และหากคุณผิดหวังกับคำสัญญา:

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

และนี่คือที่ร้องขอ


2

ด้วยjQueryและรูปแบบเล็กน้อยของคำตอบของ @ Joepreludian ด้านบน:

ประเด็นสำคัญที่ควรทราบ:

  • .one(...) แทน .on(...) or .submit(...)
  • namedแทนanonymous functionเนื่องจากเราจะอ้างถึงภายในไฟล์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...
    }
});

คุณสามารถเปลี่ยนค่าของallIsWellตัวแปรในตัวอย่างด้านล่างtrueหรือfalseเพื่อทดสอบฟังก์ชันการทำงาน:

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

โชคดี...


1

คุณสามารถใช้e.preventDefault()ซึ่งจะหยุดการทำงานปัจจุบัน

กว่าที่คุณสามารถทำได้$("#form").submit();

 $('#form').submit(function (e)
{
    return !!e.submit;
});
if(blabla...)
{...
}
else
{
    $('#form').submit(
    {
        submit: true
    });
}

มันสับสนมากสำหรับฉัน .. จะไม่ไปๆ
dapidmini

1

"การแทรกการตรวจสอบความถูกต้องโดยไม่ต้องส่งการวนซ้ำ":

ฉันแค่ต้องการตรวจสอบ reCaptcha และสิ่งอื่น ๆ ก่อนการตรวจสอบความถูกต้องของ HTML5 ดังนั้นฉันจึงทำอะไรแบบนั้น (ฟังก์ชันการตรวจสอบความถูกต้องจะคืนค่าจริงหรือเท็จ):

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

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