jQuery - ngăn mặc định, sau đó tiếp tục mặc định


102

Tôi có một biểu mẫu mà khi được gửi, tôi cần thực hiện một số xử lý bổ sung trước khi gửi biểu mẫu. Tôi có thể ngăn hành vi gửi biểu mẫu mặc định, sau đó thực hiện xử lý bổ sung của mình (về cơ bản là gọi API Google Maps và thêm một vài trường ẩn vào biểu mẫu) - và sau đó tôi cần biểu mẫu để gửi.

Có cách nào để "ngăn chặn mặc định", sau đó một thời gian "tiếp tục mặc định?"


@FelixKling Ý của bạn là stackoverflow.com/questions/7610871/… ?
M. Mimpen

Câu trả lời:


53

Sử dụng jQuery.one()

Đính kèm một trình xử lý vào một sự kiện cho các phần tử. Trình xử lý được thực thi nhiều nhất một lần cho mỗi phần tử cho mỗi loại sự kiện

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

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

Việc sử dụng onengăn chặn cũng vòng lặp vô hạn vì submitsự kiện tùy chỉnh này được phát hiện sau lần gửi đầu tiên.


2
nó sẽ gửi sau khi nhấp lại :(
tò mò

Có lẽ bạn sẽ phải đối mặt với vòng lặp vô hạn
Mehrdad HosseinNejad

Vòng lặp vô hạn, chức năng nên .Trên không .Một
sgvolpe

51

Khi bạn ràng buộc .submit()sự kiện với biểu mẫu và bạn làm những điều bạn muốn làm trước khi trả về (true), những điều này xảy ra trước khi gửi thực tế.

Ví dụ:

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

Ví dụ đơn giản

Một ví dụ khác trên jquery.com: http://api.jquery.com/submit/#entry-examples


2
bạn đang nói rằng biểu mẫu sẽ không gửi cho đến khi tất cả mã trước khi "return true;" câu lệnh được thực thi?
Developarvin

2
Vâng, đó chính xác là những gì hàm submit () làm.
Ron van der Heijden

8
Nó không phải là một ví dụ điển hình vì nó đồng bộ. Điều gì xảy ra nếu công việc tôi cần làm là cuộc gọi không đồng bộ? Vì vậy, các trường hợp được "nhấp vào gửi -> làm công cụ async và dont' gửi biểu mẫu -> trong async callback điền một số lĩnh vực theo hình thức -> gửi biểu mẫu từ callback"
The Godfather

1
Điều gì về chạy một số mã jQuery không đồng bộ ?! Cũng sẽ hoạt động?
nếnjack

điều này làm việc tuyệt vời cho tôi. Tôi sử dụng nó để kiểm soát mọi thứ trước khi gửi và nếu mọi thứ không ổn, tôi sử dụng "return false". Tôi đã tìm kiếm giải pháp này trong một ngày. cảm ơn rất nhiều.
livefreeor

26

Tôi sẽ chỉ làm:

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

Gọi preventDefaultlúc đầu và sử dụng submit()chức năng sau, nếu bạn chỉ cần gửi biểu mẫu


không liên quan đến logic bên trong trình xử lý sự kiện nhấp chuột của bạn. ủy thác nó cho người khác trách nhiệm.
Royi Namir

27
Điều này giả định chắc chắn sẽ nhấp vào một nút. Điều gì sẽ xảy ra nếu người dùng chỉ cần nhấn vào nút "enter" từ trong biểu mẫu? Điều đó cũng sẽ gửi biểu mẫu. Vì vậy, có lẽ không phải là một ý kiến ​​hay nếu dựa vào nút gửi được nhấp vào.
StackOverflowNewbie

tôi chỉ đưa ra một ví dụ về một cú nhấp chuột ... vì không có mã liên quan nào được đề cập trong câu hỏi ....
bipen

2
Trong mọi trường hợp, đoạn mã bạn cung cấp sẽ chỉ hoạt động khi người dùng nhấp vào nút. Đó không phải là cách các biểu mẫu hoạt động. Bất cứ một đề nghị nào khác?
StackOverflowNewbie

ràng buộc nhấp chuột, ngăn chặn mặc định của nó và kích hoạt nhấp chuột vào nút gửi
candjack 25/12/16

18

Sử dụng cách này Bạn sẽ thực hiện một Vòng lặp vô tận trên JS của mình. để làm một cách tốt hơn, bạn có thể sử dụng

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.

Tôi hy vọng nó sẽ giúp! Cảm ơn!


Cách tốt nhất trên thực tế, sự thay đổi với chức năng async - gist.github.com/BjornMelgaard/8ba0ee9d07c20dd8c8b3550c9df3e9ef
srghma

@bjornmelgaard Tôi phải nhớ rằng không đồng bộ là không chuẩn .
Valerio Bozz

6

Đây là IMHO, giải pháp chung nhất và mạnh mẽ nhất (nếu hành động của bạn do người dùng kích hoạt, ví dụ: 'người dùng nhấp vào nút'):

  • lần đầu tiên một trình xử lý được gọi là séc WHO đã kích hoạt nó:
    • nếu người dùng kích hoạt nó - hãy thực hiện công việc của bạn, sau đó kích hoạt lại (nếu bạn muốn) - theo chương trình
    • nếu không - không làm gì (= "tiếp tục mặc định")

Ví dụ: lưu ý giải pháp thanh lịch này để thêm "Bạn có chắc không?" bật lên bất kỳ nút nào chỉ bằng cách trang trí nút bằng một thuộc tính. Chúng tôi sẽ tiếp tục hành vi mặc định có điều kiện nếu người dùng không chọn không tham gia.

1. Hãy thêm vào mỗi nút mà chúng tôi muốn một cửa sổ bật lên "bạn có chắc" một văn bản cảnh báo:

<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. Đính kèm bộ xử lý vào TẤT CẢ các nút như vậy:

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

Đó là nó.


1
Câu trả lời chính xác! Tôi không biết rằng bạn có thể vượt qua một cuộc tranh cãi thêm để .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();
});

3

Với jQueryvà một biến thể nhỏ của câu trả lời của @ Joepreludian ở trên:

Những điểm quan trọng cần ghi nhớ:

  • .one(...) thay vào đó .on(...) or .submit(...)
  • namedthay vì anonymous functionvì chúng tôi sẽ giới thiệu nó trong 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...
    }
});

Bạn có thể thay đổi giá trị của allIsWellbiến trong đoạn mã dưới đây thành truehoặc falseđể kiểm tra chức năng:

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

Chúc may mắn...


2

Theo cách thuần túy Javascript, bạn có thể gửi biểu mẫu sau khi ngăn chặn mặc định.

Điều này là do HTMLFormElement.submit() không bao giờ gọi các onSubmit(). Vì vậy, chúng tôi đang dựa vào đặc điểm kỹ thuật đó để gửi biểu mẫu như thể nó không có trình xử lý gửi gửi tùy chỉnh ở đây.

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

Xem thao tác này để biết yêu cầu đồng bộ.


Chờ một yêu cầu không đồng bộ kết thúc cũng dễ dàng như sau:

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

Bạn có thể kiểm tra fiddle của tôi để biết ví dụ về yêu cầu không đồng bộ.


Và nếu bạn thất vọng với những lời hứa:

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

Và đây là rằng yêu cầu .


1

Bạn có thể sử dụng e.preventDefault()nó sẽ dừng hoạt động hiện tại.

hơn bạn có thể làm$("#form").submit();

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

điều này rất khó hiểu đối với tôi .. điều này sẽ không chỉ quanh quẩn sao?
dapidmini

1

"Đưa vào xác thực mà không gửi vòng lặp":

Tôi chỉ muốn kiểm tra reCaptcha và một số nội dung khác trước khi xác thực HTML5, vì vậy tôi đã làm như vậy (hàm xác thực trả về true hoặc 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();

   });
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.