jQuery-デフォルトを防止し、デフォルトを続行する


102

送信したフォームを送信する前に、追加の処理を行う必要があるフォームがあります。デフォルトのフォーム送信動作を回避してから、追加の処理(基本的にはGoogle Maps APIを呼び出していくつかの非表示フィールドをフォームに追加すること)を実行できます。次に、送信するフォームが必要です。

「デフォルトを回避」する方法はありますか、その後、「デフォルトを続行しますか?」


回答:


53

使用する jQuery.one()

要素のイベントにハンドラーをアタッチします。ハンドラーは、イベントタイプごとの要素ごとに最大1回実行されます

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

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

oneこのカスタムsubmitイベントは最初の送信後に切り離されるため、無限ループの防止も使用します。


2
再度クリックすると送信されます:(
好奇心

おそらく、無限ループに直面するでしょう
Mehrdad HosseinNejad

無限ループ、関数は.onではなく.onでなければなりません
sgvolpe

51

.submit()イベントをフォームにバインドし、返す前にやりたいことを実行すると(true)、これらのことは実際の送信の前に行われます。

例えば:

$('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」の前のすべてのコードまでフォームは送信されないと言っていますか。ステートメントが実行されますか?
developarvin

2
はい、まさにsubmit()関数が実行することです。
Ron van der Heijden 2013年

8
Synchronyousであるため、良い例ではありません。非同期呼び出しが必要な場合はどうなりますか?したがって、ケースは「送信をクリック->非同期処理を行い、フォームを送信しない->非同期コールバックでフォームの一部のフィールドに入力する->コールバックからフォームを送信する」
Godfather

1
非同期jQueryコードを実行するのはどうですか?うまくいきますか?
ろうそくのジャック

これは私にとってはうまくいきます。送信する前にそれを制御するために使用し、正しくない場合は「return false」を使用します。私はこの解決策を一日探しました。どうもありがとう。
livefreeor 2017年

26

私はただやります:

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

フォームを送信するだけの場合は、preventDefault最初に呼び出し 、submit()後で関数を使用します


クリックイベントハンドラー内にロジックを含めないでください。それを他人の責任に委任してください。
Royi Namir 2013

27
これは確かにボタンをクリックすることを前提としています。ユーザーがフォーム内から「Enter」ボタンを押すとどうなりますか?それもフォームを送信します。そのため、送信ボタンがクリックされることを信頼することは、おそらくお勧めできません。
StackOverflowNewbie 2013年

質問に関連するコードが記載されていなかったので、クリックの例を挙げていました...
bipen

2
いずれの場合も、指定したスニペットは、ユーザーがボタンをクリックした場合にのみ機能します。それはフォームが機能する方法ではありません。他に何か提案はありますか?
StackOverflowNewbie 2013年

クリックをバインドし、デフォルトを防止して、送信ボタンのクリックをトリガーします
キャンドルジャック

18

この方法を使用すると、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.

お役に立てば幸いです。ありがとう!


最良の方法、非同期関数によるバリエーション-gist.github.com/BjornMelgaard/8ba0ee9d07c20dd8c8b3550c9df3e9ef
srghma

@bjornmelgaard非同期は非標準であることを覚えておく必要があります。
Valerio Bozz 2018

6

これは、IMHO、最も一般的で堅牢なソリューションです(アクションがユーザーによってトリガーされる場合(たとえば、「ユーザーがボタンをクリックする」など):

  • ハンドラーが初めて呼び出されたときに、WHOがトリガーしたことを確認します。
    • ユーザーがそれをタイガーした場合-あなたの仕事をしてから、それをもう一度トリガーします(必要な場合)-プログラムで
    • それ以外の場合-何もしない(=「デフォルトを続行」)

例として、「Are you sure?」を追加するこのエレガントなソリューションに注意してください。属性でボタンを装飾するだけで、任意のボタンにポップアップします。ユーザーがオプトアウトしない場合は、デフォルトの動作を条件付きで継続します。

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

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

  // Do some stuff here
  ...

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

3

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>

幸運を...


2

純粋なJavascriptの方法では、デフォルトを防止した後でフォームを送信できます。

これは、あるHTMLFormElement.submit() 呼び出すことはありませんonSubmit()。したがって、ここではカスタムonsubmitハンドラーがないかのようにフォームを送信するために、その仕様の奇妙さに依存しています。

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

同期リクエストについては、このフィドルを参照してください。


非同期リクエストが完了するのを待つのも同じくらい簡単です。

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

そして、これがそのリクエストです。


1

e.preventDefault()現在の操作を停止するのに使用できます。

あなたができるより$("#form").submit();

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

これは私にとって非常に混乱します。
dapidmini

1

「送信ループのない検証インジェクション」:

HTML5検証の前にreCaptchaやその他の要素を確認したいだけなので、そのようなことをしました(検証関数はtrueまたは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();

   });
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.