web-dev-qa-db-ja.com

jQuery:フォーム送信時にどのボタンがクリックされたのか?

フォーム送信用に設定された.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()イベントを適用する以外に、どの送信ボタンがクリックされたかを判断する方法はありますか?

203
hawkexp

私はこれと同じ質問をしました: どうすればフォーム送信イベントから送信を引き起こしたボタンを得ることができますか?

私はこの解決策を思いついたことになった、そしてそれはかなりうまくいった:

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

複数のフォームを使用している場合は、これを少し微調整する必要があるかもしれませんが、それでも適用されるはずです。

218
hunter

私はこれがうまくいったことがわかりました。

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

これは私のために働く:

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

フォームが送信されたとき:

  • document.activeElementはクリックされた送信ボタンをあなたに与えます。

  • document.activeElement.getAttribute('value')はあなたにそのボタンの値を与えます。

41
Nick F

これが私の目的のためによりきれいに見えるアプローチです。

まず、ありとあらゆる形について:

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

このclickイベントがフォームに対して発生すると、後でアクセスできるように元のターゲット(イベントオブジェクトで使用可能)を単に記録します。これはフォーム上の任意の場所でクリックされるたびに発生するため、かなり広い範囲のストロークです。最適化のコメントは大歓迎ですが、それが顕著な問題を引き起こすことは決してないと思います。

次に、$( 'form')。submit()で、最後にクリックされた内容を照会できます。

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

うわー、いくつかの解決策は複雑になることができます!単純なグローバルを使用しても構わない場合は、入力ボタンのクリックイベントが最初に発生するという事実を利用してください。 $( '#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);
      });
    });
13
lawnbowler

最善の解決策は

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

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

7
Thomas Williams

他の可能な解決策はあなたのフォームに隠しフィールドを追加することです:

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

今度はsubmitionハンドラのフォームで隠し変数を読み、それに基づいて決定します。

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

Stanとyann-hが行ったことに基づいて構築されていますが、これはデフォルトの最初のボタンです。この全体的なアプローチの利点は、クリックと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;
6
andrewmo

.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 );
}
4
jcane86

これは私のために働いた

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

}
4
Saheb Mondal

私は受け入れられた答えにコメントすることができないので、私はここにフォームの外側にある要素を考慮に入れるべきである修正されたバージョンを持ってきます(すなわち: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]');
})
3
user3074069

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

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

サイドノート:私は個人的にJavaScript経由で送信されるすべてのフォームにクラスform-jsを追加しています。

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

隠しフィールドを追加

3
anydasa

これは私が使用したソリューションであり、非常にうまく機能します。

// 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>
2
vasilenicusor

Stan answerに似ていますが:

  • 複数のボタンがある場合は、最初のボタンだけを取得する必要があります=> [0]
  • フォームをEnterキーで送信できる場合は、default => 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
yann-h

それは私を助けました https://stackoverflow.com/a/17805011/1029257

送信ボタンがクリックされた後にのみフォームがサブミットされました。

var theBtn = $(':focus');
if(theBtn.is(':submit'))
{
  // ....
  return true;
}

return false;
1
w4kskl

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

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

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

RETURNキーでクリックイベントを送信するためにブラウザを使わずにキーとマウス/指の両方でナビゲートしたときに動作します(ただし、問題ありません)。

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

デモでは、選択したアイテムを示す赤い枠と、名前と値/ラベルを示す警告を設定しました。

これが FIDDLEです

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

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
FrancescoMM

ボタンの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がsubmit(?)の前に発生した場合、これは動作しますが、それが常に正しいかどうかはわかりません。

0
darekk

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

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"));
0
BabiBN

私も解決策を作りました、そしてそれは非常にうまくいきます:
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.
        }
    });

お役に立てれば!乾杯!

0
Jason Cidras