jQuery:フォームの送信時にクリックされたボタンを取得する方法は?


227

.submit()フォーム送信用に設定されたイベントがあります。ページにも複数のフォームがありますが、この例では1つだけです。.click()それぞれにイベントを適用せずにクリックされた送信ボタンを知りたいのですが。

これが設定です:

<html>
<head>
  <title>jQuery research: forms</title>
  <script type='text/javascript' src='../jquery-1.5.2.min.js'></script>
  <script type='text/javascript' language='javascript'>
      $(document).ready(function(){
          $('form[name="testform"]').submit( function(event){ process_form_submission(event); } );
      });
      function process_form_submission( event ) {
          event.preventDefault();
          //var target = $(event.target);
          var me = event.currentTarget;
          var data = me.data.value;
          var which_button = '?';       // <-- this is what I want to know
          alert( 'data: ' + data + ', button: ' + which_button );
      }
  </script>
</head>
<body>
<h2>Here's my form:</h2>
<form action='nothing' method='post' name='testform'>
  <input type='hidden' name='data' value='blahdatayadda' />
  <input type='submit' name='name1' value='value1' />
  <input type='submit' name='name2' value='value2' />
</form>
</body>
</html>

jsfiddleのライブ例

各ボタンに.click()イベントを適用する以外に、どの送信ボタンがクリックされたかを判別する方法はありますか?


2
もちろん、皮肉なことに、この情報はサーバー側を決定するのに重要ではありません。
Neil、

5
@Neil $ .ajax()およびserializeArray()を介してフォームを送信する場合は不可。
アーロン


1
リスナーを送信ボタンに配置し、フォームを手動で送信するのはどうでしょう。
JMRC 2018

1
シリアル化されたバージョンのフォームデータを見て、ボタンと一致するのはnameどうですか。
オーガスティンリーディンガー

回答:


235

私はこれと同じ質問をしました:フォーム送信イベントから送信の原因となったボタンを取得するにはどうすればよいですか?

私はこのソリューションを思いついたので、それはかなりうまくいきました:

$(document).ready(function() {
    $("form").submit(function() { 
        var val = $("input[type=submit][clicked=true]").val();
        // DO WORK
    });
    $("form input[type=submit]").click(function() {
        $("input[type=submit]", $(this).parents("form")).removeAttr("clicked");
        $(this).attr("clicked", "true");
    });
});

複数のフォームを持つあなたの場合、これを少し調整する必要があるかもしれませんが、それはまだ適用されるべきです


11
+1素晴らしい解決策。フォームの送信がajaxで処理され、事前にボタンが再度クリックされないようにする場合は、ボタン全体でクリックされた属性をfalseにリセットするステートメントを追加できます。
チャンドゥ

1
ああなるほど。独自の「クリック」属性を追加しています。私は「クリックした」ブール値を探し回っていましたが、どこにも見つかりませんでした。私は自分で作るつもりはありませんでした。良いアイデア!
hawkexp

9
これはボタン要素ではなく入力要素でのみ機能することに注意してください。
Bob.at.Indigo.Health 2015年

1
これはボタン要素のあるChromeでは不要です。私は単に送信イベントを処理し、フォームからFormDataオブジェクトを作成します。これには、クリックされたボタンの値が常に含まれています。FireFoxはこの動作を示さず、代わりにボタンの値をまったく送信しません。Chromeは上記のソリューションのようなことを自動的に行っているようで、どのボタンがクリックされたかを記憶し、それをフォームデータに自動的に含めます。もちろん、この標準的な動作の欠如(とにかくJavaScriptですべてにプラグインするので、私は驚かない)で、この機能は役に立たなくなります。
Triynko 2015年

1
また、submit要素は入力タグである必要がないため、セレクター "button [type = submit]"(カンマ区切り)の追加を検討してください。
Kyselejsyreček

91

これでうまくいくことがわかりました。

$(document).ready(function() {
    $( "form" ).submit(function () {
        // Get the submit button element
        var btn = $(this).find("input[type=submit]:focus" );
    });
}

12
このソリューションはChromeでは適切に機能しますが、Safariでは機能せず、ボタンオブジェクトではなく未定義を返します
Sun Lin氏

1
@Krinkle可能な限り最も一般的な方法を示すためにそのようにコード化しました。開発者は自分の好みに合わせて最適化できるほど賢いと思います。
2014

他のソリューションよりもきれいです。
Enterキーを

この回答は常に機能するとは限りません。実際には、フォーカスされたボタンではなくクリックされたボタンが必要です(フォーカスアクションはクリックアクションではないため)。(ハンターの)選択された答えは正しいものです。
Vasil Popov

私は送信ボタンのクリックイベントとフォームの送信イベントを持っています...後者は前者をトリガーします。これを使用して、イベントのソースを特定しました。一部のブラウザでは、ボタンをクリックすると、ボタンがフォーカスされた状態で表示され、他のブラウザでは何も表示されません。私がテストしたすべてのブラウザで、入力中にEnterキーを押すと、入力に焦点が当てられたままになります。
notacouch 2015年

65

これは私にとってはうまくいきます:

$("form").submit(function() {
   // Print the value of the button that was clicked
   console.log($(document.activeElement).val());
}

3
これは役に立ちました、を取得するidためにactiveElement、私はそうしました$(document.activeElement).attr('id');
Mikolaj

9
何それの価値について、あなたはIDを取得するためにjQueryを使用する必要はありません-それは純粋なJavascriptを使用しても、簡単です:document.activeElement.id
ニック・F

5
これはSafariでは期待どおりに機能しないようです。:(
rinogo 2017年

@rinogo:Safariでは何が起こりますか?
クレセントフレッシュ

1
Safari document.activeElementでは入力ではありません。私の場合、それはモーダルdiv(フォームを含む)です。
mgalgs 2018年

46

フォームが送信されると:

  • document.activeElement クリックされた送信ボタンが表示されます。

  • document.activeElement.getAttribute('value') そのボタンの値を提供します。


2
これはSafariでは期待どおりに機能しないようです。:(
rinogo

Safariについてはわかりませんが、Chromeではうまくいきました:)ありがとう!
インガス、2017

Chrome 63およびIE11で動作
クリスパロット卿18年

私はjquery控えめな検証を実行していたが、これはこの前にインターセプトし、無効な入力をボタンではなくactiveElementとして設定します。
Peheje

28

私の目的にとってよりクリーンに見えるアプローチは次のとおりです。

まず、すべてのフォームについて:

$('form').click(function(event) {
  $(this).data('clicked',$(event.target))
});

このクリックイベントがフォームに対して発生すると、後でアクセスされる元のターゲット(イベントオブジェクトで利用可能)が記録されるだけです。フォーム上のどこをクリックしても発火するため、これはかなり広いストロークです。最適化のコメントは歓迎しますが、目立った問題が発生することはないと思います。

次に、では$('form').submit()、最後にクリックされたものを問い合わせることができます。

if ($(this).data('clicked').is('[name=no_ajax]')) xhr.abort();

これがクリックではなくフォーム送信イベントの場合はどうなりますか?
トニー

1
@トニー、ごめんなさい、あなたの質問がもっと早く見えませんでした。この回答は、完全にフォームの送信に関するものです。送信ボタンもクリックされるため、クリックイベントが発生します。
ジョナサンカメニッシュ

2
フォームの送信イベントが子要素のクリックイベントの前に発生するため、ハンターの回答よりもこの回答を支持します。これにより、フォームの送信イベントがでキャンセルされたときに問題が発生return falseしますが、クリックはフォームの子ではなくフォームにバインドされるため、このメソッドは正しく機能します。
pospi 2013年

7
これは、フォームがクリック以外の方法で送信された場合(Enterキーを押すなど)を適切に処理できません。フォームが他の方法で送信される場合、送信イベントをトリガーしたのは最初に送信されたボタンであり、最後にクリックされたボタンではありません。
quietmint 2013

セミコロンが後に欠けて... $(event.target))いますが、編集は6文字以上でなければならないため編集できません
Hafenkranich

13

うわー、いくつかのソリューションは複雑になる可能性があります!単純なグローバルを使用してもかまわない場合は、入力ボタンのクリックイベントが最初に発生するという事実を利用してください。$( '#myForm input')を使用して、多くのフォームの1つに対して$( 'input')セレクターをさらにフィルターできます。

    $(document).ready(function(){
      var clkBtn = "";
      $('input[type="submit"]').click(function(evt) {
        clkBtn = evt.target.id;
      });

      $("#myForm").submit(function(evt) {
        var btnID = clkBtn;
        alert("form submitted; button id=" + btnID);
      });
    });

12

私は最良の解決策を見つけました

$(document.activeElement).attr('id')

これは入力だけでなく、ボタンタグでも機能します。また、ボタンのIDを取得します。


私のページがSafariで機能するかどうかを確認する必要があります。なぜサファリはいつもそんなに難しいものでなければならないのですか?それをありがとう。家に着いたらチェックする
トーマスウィリアムズ


これはSafariでは機能しません。本文のButtonのリスナーをクリックすると、フォームの.submitが呼び出されます。送信ハンドラー内で$(document.activeElement).attr('id')戻りますundefined
dyodji

7

別の可能な解決策は、フォームに非表示フィールドを追加することです。

<input type="hidden" id="btaction"/>

次に、ready関数に関数を追加して、どのキーが押されたかを記録します。

$('form#myForm #btnSubmit').click(function() {
    $('form#myForm #btaction').val(0);
});

$('form#myForm #btnSubmitAndSend').click(function() {
    $('form#myForm #btaction').val(1);
});

$('form#myForm #btnDelete').click(function() {
    $('form#myForm #btaction').val(2);
});

次に、フォーム送信ハンドラーが隠し変数を読み取り、それに基づいて決定します。

var act = $('form#myForm #btaction').val();

6

Stanとyann-hが行ったことを基にしていますが、これはデフォルトで最初のボタンに設定されています。この全体的なアプローチの優れた点は、クリックとEnterキーの両方を取得できることです(フォーカスがボタンになかった場合でも。フォームでEnterを許可する必要がある場合は、ボタンがフォーカスされたときにこれに応答するだけです(つまり、スタンの答えです。私の場合、ユーザーの現在のフォーカスがテキストボックスにある場合でも、Enterキーでフォームを送信できるようにしたいと考えました。

「id」ではなく「name」属性も使用していましたが、これは同じアプローチです。

var pressedButtonName =
     typeof $(":input[type=submit]:focus")[0] === "undefined" ?
     $(":input[type=submit]:first")[0].name :
     $(":input[type=submit]:focus")[0].name;

したがって、Tabで2番目のボタンにフォーカスを移動してRETURNキーを押すと、デフォルトで最初のボタンに戻ります...
FrancescoMM

5

これは私のために働いた

$('#Form').submit(function(){
var btn= $(this).find("input[type=submit]:focus").val();
alert('you have clicked '+ btn);

}

これはメダルに値します!
MartinZvarík

4

.clickイベントを追加しないことの意味が、それらのイベントに個別のハンドラーを必要としない場合は、1つの関数ですべてのクリック(送信)を処理できます。

$(document).ready(function(){
  $('input[type="submit"]').click( function(event){ process_form_submission(event); } );
});

function process_form_submission( event ) {
  event.preventDefault();
  //var target = $(event.target);
  var input = $(event.currentTarget);
  var which_button = event.currentTarget.value;
  var data = input.parents("form")[0].data.value;
//  var which_button = '?';       // <-- this is what I want to know
  alert( 'data: ' + data + ', button: ' + which_button );
}

悪くないアイデア。これはページ上の任意の数のフォームで機能しますか?
hawkexp

@ホークうん、そうだ。これが望ましい動作であるかどうかはわかりませんが、コードは実際にはフォームを送信しないので、私の場合もそうではありません。送信したい場合は、を削除するevent.preventDefaultか、などを実行してくださいinput.parents("form")[0].submit()
jcane86 2011

そして、あなたがクリック(リターンキー?)せずに送信する場合、それは総混乱になります...
FrancescoMM

4

受け入れられた回答についてコメントすることはできないので、フォームの外にある要素(つまり、form属性を使用してフォームに添付される)を考慮に入れるべき修正バージョンをここに持ってきます。これは最新のブラウザ用です:http : //caniuse.com/#feat=form-attributeclosest('form') サポートされていないのフォールバックとして使用されているform属性

$(document).on('click', '[type=submit]', function() {
    var form = $(this).prop('form') || $(this).closest('form')[0];
    $(form.elements).filter('[type=submit]').removeAttr('clicked')
    $(this).attr('clicked', true);
});

$('form').on('submit', function() {
    var submitter = $(this.elements).filter('[clicked]');
})

これは本当に選択された答えになるはずです。ルールは次のように追加するだけです"button,[type=submit]"
Wil

@Wilですが、すべてのボタンが送信ボタンであるとは限りません。ボタンのタイプによって異なります。
ptyskju

はい、ただし<input type = "submit">]がない場合、これまでに使用したすべてのUAは<button>タグをフォーム送信トリガーとして処理したため、これはそのケースをキャッチします。または、作成者は、すべての送信可能な要素に[type = submit]プロパティが必要であるという警告を追加できます。
Wil

3
$("form input[type=submit]").click(function() {
    $("<input />")
        .attr('type', 'hidden')
        .attr('name', $(this).attr('name'))
        .attr('value', $(this).attr('value'))
    .appendTo(this)
});

非表示フィールドを追加


Firefox 30 / Windows 7では機能しません。注:オンサブミットイベントでjquery's:this.submit()を使用して送信された場合、クリックされた送信値を送信しない可能性があるため、非表示フィールドは現在Firefoxで必須です。$(this).attr( 'name')がすべてのブラウザーで機能しない可能性があることを少し心配しています。
user1610743 14

Firefox 30 / Windows 7を使用しています。すべてが完全に動作しています。
anydasa 14

button[type=submit]およびを含めることを忘れないでくださいinput[type=image]
rybo111 2015年

3

私にとって、最良の解決策はこれでした:

$(form).submit(function(e){

   // Get the button that was clicked       
   var submit = $(this.id).context.activeElement;

   // You can get its name like this
   alert(submit.name)

   // You can get its attributes like this too
   alert($(submit).attr('class'))

});

3

作業この素晴らしい答え、あなたはハンドラを提出する能動素子(ボタン)、追記形に隠された入力をチェックし、必要に応じての最後にそれを削除することができます。

$('form.form-js').submit(function(event){
    var frm = $(this);
    var btn = $(document.activeElement);
    if(
        btn.length &&
        frm.has(btn) &&
        btn.is('button[type="submit"], input[type="submit"], input[type="image"]') &&
        btn.is('[name]')
    ){
        frm.append('<input type="hidden" id="form-js-temp" name="' + btn.attr('name') + '" value="' + btn.val() + '">');
    }

    // Handle the form submit here

    $('#form-js-temp').remove();
});

補足:form-jsJavaScriptを介して送信されるすべてのフォームに個人的にクラスを追加します。


2

スタンアンサーに似ていますが、

  • 複数のボタンがある場合、最初のボタンのみを取得する必要があります=> [0]
  • Enterキーでフォームを送信できる場合は、デフォルトを管理する必要があります=> myDefaultButtonId

$(document).on('submit', function(event) {
    event.preventDefault();
    var pressedButtonId = 
         typeof $(":input[type=submit]:focus")[0] === "undefined" ? 
         "myDefaultButtonId" :
         $(":input[type=submit]:focus")[0].id;
    ...
 }

2

これは私が使用する解決策であり、非常にうまく機能します:

// prevent enter key on some elements to prevent to submit the form
function stopRKey(evt) {
  evt = (evt) ? evt : ((event) ? event : null);
  var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
  var alloved_enter_on_type = ['textarea'];
  if ((evt.keyCode == 13) && ((node.id == "") || ($.inArray(node.type, alloved_enter_on_type) < 0))) {
    return false;
  }
}

$(document).ready(function() {
  document.onkeypress = stopRKey;
  // catch the id of submit button and store-it to the form
  $("form").each(function() {
    var that = $(this);

    // define context and reference
    /* for each of the submit-inputs - in each of the forms on
			 the page - assign click and keypress event */
    $("input:submit,button", that).bind("click keypress", function(e) {
      // store the id of the submit-input on it's enclosing form
      that.data("callerid", this.id);
    });
  });

  $("#form1").submit(function(e) {
    var origin_id = $(e.target).data("callerid");
    alert(origin_id);
    e.preventDefault();

  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form id="form1" name="form1" action="" method="post">
  <input type="text" name="text1" />
  <input type="submit" id="button1" value="Submit1" name="button1" />
  <button type="submit" id="button2" name="button2">
    Submit2
  </button>
  <input type="submit" id="button3" value="Submit3" name="button3" />
</form>



1

これが私の解決策です:

   $('#form').submit(function(e){   
        console.log($('#'+e.originalEvent.submitter.id));
        e.preventDefault();
    });

0

私も解決策を作りました、そしてそれはかなりうまくいきます:
それはjQueryとCSSを使用します


最初に、簡単なCSSクラスを作成しました。これを埋め込むか、別のファイルに含めることができます。

<style type='text/css'>
    .Clicked {
        /*No Attributes*/
    }
</style>


次に、フォーム内のボタンのクリックイベントで、CSSクラスをボタンに追加します。ボタンに既にCSSクラスがある場合は、それを削除します。(2つのCSSクラスは必要ありません(念のため))。

    // Adds a CSS Class to the Button That Has Been Clicked.
    $("form :input[type='submit']").click(function () 
    {
        if ($(this).hasClass("Clicked"))
        {
            $(this).removeClass("Clicked");
        }
        $(this).addClass("Clicked");
    });


次に、ボタンをテストして、CSSクラスがあることを確認します。テストしたボタンにCSSがない場合は、他のボタンにあります。

    // On Form Submit
    $("form").submit(function ()
    {
        // Test Which Button Has the Class
        if ($("input[name='name1']").hasClass("Clicked"))
        {
            // Button 'name1' has been clicked.
        }
        else
        {
           // Button 'name2' has been clicked.
        }
    });

お役に立てれば!乾杯!


button[type=submit]およびを含めることを忘れないでくださいinput[type=image]
rybo111 2015年

スタイル設定とCSSへの参照を削除する必要があります-ここでは関係ありません。また、同じクラスを2回追加しないので、使用hasClass()removeClass()て冗長な行addClass()
rybo111 2015年

0

ボタンID情報のホルダーとしてinput type = "hidden"を作成できます。

<input type="hidden" name="button" id="button">
<input type="submit" onClick="document.form_name.button.value = 1;" value="Do something" name="do_something">

この場合、フォームは送信時に値 "1"(ボタンのID)を渡します。これは、送信(?)の前にonClickが発生した場合に機能しますが、常にtrueであるかどうかはわかりません。


0

どの<button>または<input type = "button" ...>が押されているかを区別する簡単な方法は、それらの 'id'を確認することです。

$("button").click(function() {
  var id = $(this).attr('id');
  ... 
});

0

this.formを使用して、送信先の正しいフォームを取得するサンプルと、最後にクリック/フォーカスされた要素を格納するデータフィールドを次に示します。また、送信コードをタイムアウト内にラップして、実行前にクリックイベントが発生することを確認しました(一部のユーザーは、送信後にChromeでクリックイベントが発生することがあるとコメントで報告しています)。

キーとマウス/指の両方でナビゲートし、ブラウザに頼らずにRETURNキーのクリックイベントを送信するときに動作します(ただし、害はありません)。ボタンとフィールドのフォーカスイベントのイベントハンドラーを追加しました。

クリックすると保存されるアイテムにtype = "submit"のボタンを追加できます。

デモでは、選択したアイテムと名前と値/ラベルを表示するアラートを表示するように赤い枠を設定しました。

こちらがフィドルです

そしてこれが(同じ)コードです:

JavaScript:

$("form").submit(function(e) {
  e.preventDefault();
  // Use this for rare/buggy cases when click event is sent after submit
  setTimeout(function() {

    var $this=$(this);
    var lastFocus = $this.data("lastFocus");
    var $defaultSubmit=null;

    if(lastFocus) $defaultSubmit=$(lastFocus);

    if(!$defaultSubmit || !$defaultSubmit.is("input[type=submit]")) {
      // If for some reason we don't have a submit, find one (the first)
      $defaultSubmit=$(this).find("input[type=submit]").first();
    }

    if($defaultSubmit) {
      var submitName=$defaultSubmit.attr("name");
      var submitLabel=$defaultSubmit.val();

       // Just a demo, set hilite and alert
      doSomethingWith($defaultSubmit);
      setTimeout(function() {alert("Submitted "+submitName+": '"+submitLabel+"'")},1000);
    } else {
      // There were no submit in the form
    }

  }.bind(this),0);

});

$("form input").focus(function() {
  $(this.form).data("lastFocus", this);
});
$("form input").click(function() {
  $(this.form).data("lastFocus", this);
});

// Just a demo, setting hilite
function doSomethingWith($aSelectedEl) {
  $aSelectedEl.css({"border":"4px solid red"});
  setTimeout(function() { $aSelectedEl.removeAttr("style"); },1000);
}

ダミーHTML:

<form>
<input type="text" name="testtextortexttest" value="Whatever you write, sir."/>
<input type="text" name="moretesttextormoretexttest" value="Whatever you write, again, sir."/>

<input type="submit" name="test1" value="Action 1"/>
<input type="submit" name="test2" value="Action 2"/>
<input type="submit" name="test3" value="Action 3"/>
<input type="submit" name="test4" value="Action 4"/>
<input type="submit" name="test5" value="Action 5"/>
</form>

DUMB CSS:

input {display:block}

0

私を助けるこの関数を書きます

var PupulateFormData= function (elem) {
var arr = {};
$(elem).find("input[name],select[name],button[name]:focus,input[type='submit']:focus").each(function () {
    arr[$(this).attr("name")] = $(this).val();
});
return arr;
};

次に使用

var data= PupulateFormData($("form"));


-1

次のようにwindow.event.srcElement.idを使用します。

function clickTheButton() {

var Sender = window.event.srcElement;
alert("the item clicked was " + Sender.id)

}

次のようなボタンの場合:

<input type="button" id="myButton" onclick="clickTheButton();" value="Click Me"/>

「クリックしたアイテムはmyButtonでした。

改善された例では、window.event.srcElementをprocess_form_submissionに追加でき、プロセスを呼び出した要素への参照ができます。


1
要素にはonclickを使用しないでください。非推奨です
Krzysztof Cygan '19

1
これは送信ボタンでは機能しないようです。window.event.srcElementがフォームのIDを返しています。
333Mhz

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