質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.21%

ajaxのsubmitでreturn falseが効かない

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,093

SugiuraY

score 249

過去に質問をさせていただき、eturn falseすることによりイベントをsubmitイベントをキャンセルできることを学ぶことができました。
これを応用して、下記のコードの通り
1) まず最初のthenでerrorがあればerrCode[]に格納される。
2) 次のthenでerrCode[]のlengthが1以上であることを条件(エラーがある)、errStatusに"YES"を格納
3) 次のthenでrrCode[]のlengthが0以下であることを条件(エラーがない)、errStatusに"NO"を格納
*2)と*3)を別のthenで処理する意味は本来なのですが、便宜上、ここでは分けています
4) 最後にajax外でerrStatusを判定することにより、return falseでキャンセルさせます

ここで、submitイベントがキャンセルされません
直前にerrStatusを出力しても、何も出力されません("").
前の質問でこのような方法で外で判定すべきとのアドバイスをいただいたのですが、実現の仕方がわからなくなってしまいました。

また、同期非同期の順番を読み解いていてthenとdoneで最後にすべて成功した場合
doneが処理されるとなっていたので、ajaxの外ではなく中のdoneとして以下のようなコードも試してみたのですが、
このばあerrStatusにはyes/noが正しく格納されたのですが、return falseが正しく実行されず、submitがキャンセルされませんでした。

.done(function(){
alert(errStatus);//適切にerrStatusにyes/noが格納されていることを確認した
if(errStatus=="yes"){
return false;
}else if(errStatus=="no"){
$("#form_a").submit();
}
})

やりたいこととしては、ajaxでエラーの判定を行い、エラーがあればerrStatusにyesを格納し、return falseでsubmitをキャンセル、エラーがなければそのままsubmitを実行されるなのですが、これらのコードの問題点及び解決法についてアドバイスを願えますでしょうか。

よろしくお願い申し上げます。

<form id="form_a" action="" method="POST">
 <input type="text">
 <button form="form_a" type="submit">送信<button>
</form>
$(function(){

$("#form_a").on('submit',function(){
    const errCode = [];
    var errStatus="";
      $.ajax({
        type:'POST',
        url:'hoge.php',
        datatype:'json',
        data:{
        xxx:xxx,
        yyy:yyy
        }
        })
        .then(
          function(data){
              errCode.push("a")              
          }
        ,function(){
              alert('通信に失敗しました、通信環境を確認してください');
        }).then(function(){
              if (errCode.length>0) {
              errStatus ="yes";
              }
        },function(){
              alert('通信に失敗しました、通信環境を確認してください');
        }).then(function(){
              if (errCode.length<1) {
              errStatus="no";
              },function(){
              alert('通信に失敗しました、通信環境を確認してください');
          })
         //alert(errStatus);//試しに出力
              if(errStatus=="yes"){
              return false;
              }
    })
})
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+5

ajaxは非同期で実行されます。errStatusを書き換える前にsubmitイベントに登録した関数は終了しています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/17 12:57

    コメント誠にありがとうございます。
    非同期処理が継続しており、submitイベントが先に処理されてしまっていることがわかりました。
    thenを使用することで、順番を制御できると勘違いしていました。
    doneを使用すれば、thenの処理を待つのですが、doneの中でのretun falseはsubmitイベントのキャンセルを意味するわけではないようですので、
    errStatusに変数を格納させてから、ajaxの外でsubmit処理のを分岐させるやり方を考えてみます。
    トライアンドエラーに時間を要するため、一旦コメントバックをさせていただきます。
    よろしくお願い申し上げます。

    キャンセル

  • 2019/06/17 14:39

    >トライアンドエラーに
    すごーく細かくて申し訳ないですが正確には trial and error です。
    ※日本人に間違って広がった英語慣用句の筆頭ですね

    キャンセル

  • 2019/06/17 22:02

    ご指摘ありがとうございます。名詞 and 名詞が正しいですよね。
    またひとつ勉強になりました!

    キャンセル

checkベストアンサー

+2

ajaxが伴うのでしたらformのsubmitイベントを拾うより
buttonをtype=buttonにしてそのbuttonのclickイベントを拾って処理を行い、
submitは別途自前で.submit()にて送信したほうが良いでしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/17 12:34

    コメントありがとうございます。
    以前の投稿させていただいた質問で、inputフォーカス時にenterでsubmitを実行させたいと言う内容で
    この点はhtmlの標準機能を活かすべきと言うことで、button type="submit"として、form側でsubmitイベントを拾う方向で考えておりました。
    https://teratail.com/questions/193599
    button type="button"でsubmitイベントを拾う場合、enterでのsubmitイベントを実行させるために、入力キーを受け取る方法しか思いつかなかったのですが、キーボードの違い等がある場合、不安定な処理となるため、採用を辞めました。。

    キャンセル

  • 2019/06/17 12:40 編集

    んーであれば冒頭でpreventDefaultで止めるとか
    https://developer.mozilla.org/ja/docs/Web/API/Event/preventDefault
    ですが、「formのsubmitのイベント」を拾っている時点でsubmitは始まっているのでせめてボタンのクリックイベントにしてください。

    キャンセル

  • 2019/06/17 14:30

    コメントありがとうございます。
    確かにbuttonでもsubmitしていて、formでもsubmit()で処理しているのは重複しておりますね。。
    ご指摘いただき、ありがとうございます。

    キャンセル

0

こんな感じで処理してください

$(function(){
  var d=$.Deferred();
  var errStatus='';
  $.when($.ajax({
  type:'POST',
  url:'hoge.php',
  dataType:'json',
  }).then(function(data){
    d.resolve("no");
    return d.promise();
  },function(xhr,err){
    d.resolve("yes");
    return d.promise();
  })).then(function(data){
    errStatus=data;
    console.log(errStatus);
  });
});

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/17 12:53

    コメントありがとうございます。
    完全に私の不勉強のせいではありますが、調べていく中でthenを利用することで同期処理のようなことが実現できると勘違いしておりました。
    https://qiita.com/sukobuto/items/0ee5026776e1bab10fb4
    実際にはthenだけでつないでも非同期処理が続いていて、意図した順番で処理をしているわけではないと推察します。
    それでもdoneで繋げば、最後のdoneまで処理を待つのでretuen falseをすれば実装できると思ったのですが、そういうわけではないのですね。(おそらくajaxの外でreturn falseしないとsubmitイベントをキャンセルできない)
    Deferredでpromise/resolveを使えば順番を処理の順番をコントロールできるものと思いますが、少し調べながら動作を確認するため、ご提供いただいたコードベースのチェックにお時間をいただきたく、先にお礼のコメントに留めさせていただきます。
    *いつも検証に時間がかかるので、先にお礼のお返事をするのか、しっかり時間をとって検証してからコメントするのか迷うのですが、不躾かと思い、一旦コメントバックさせていただいております。

    キャンセル

  • 2019/06/17 13:00

    $.ajaxのfailはいわゆるreject処理なので、$.whenでも成功ルートに
    データが流れません
    $.ajaxのthenの2番目のコールバックでresolveするとそこから
    成功ルートに流れるので$.whenのthenの1番目のコールバックに
    処理が流れます

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる