jQuery:如何获取提交表单时单击的按钮?


227

.submit()为提交表单设置了一个活动。我在页面上也有多种形式,但是在此示例中只有一种形式。我想知道在不对.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
具有讽刺意味的是,此信息对于确定服务器端很重要。
尼尔,

5
@Neil如果不是通过$ .ajax()和表单上的serializeArray()提交表单,则不会。
亚伦


1
如何将侦听器置于“提交”按钮上并手动提交表单。
JMRC

1
如何查看表格数据的序列化版本并按一下按钮进行匹配name
奥古斯丁·里丁格19'Sep

Answers:


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不错的解决方案。您可能需要添加一条语句,以将表单中的clicked属性重置为false,以防表单提交以Ajax方式处理,并且您希望避免再次被预先单击的按钮。
Chandu

1
哦,我明白了。您正在添加自己的“ clicked”属性。我到处都在寻找“单击”布尔值,在任何地方都找不到。我从没想过要自己做。好主意!
hawkexp 2011年

9
请注意,这仅适用于输入元素,不适用于按钮元素。
Bob.at.Indigo.Health

1
在带有按钮元素的Chrome中,这是不必要的。我只处理on Submit事件,从表单构造一个FormData对象,它始终包含被单击的按钮的值。FireFox不会表现出这种现象,而是根本不发送按钮值。Chrome似乎会自动执行上述解决方案,记住点击了哪个按钮并将其自动包含在表单数据中。当然,这种标准行为的缺乏(无论如何都会困扰JavaScript中的所有内容,因此我并不感到惊讶)使该功能无用。
Triynko 2015年

1
另外,考虑添加选择器“ 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上却无法运行,它将返回未定义的内容,而不是按钮对象
孙林先生

1
@Krinkle我这样编码,以显示可能的最通用方法。我认为开发人员足够聪明,可以根据自己的喜好对其进行优化。
Stan 2014年

比其他解决方案更清洁。仍然没有找到可以在按Enter键时起作用的解决方案
andrewtweber 2014年

这个答案将永远不会起作用。实际上,您需要单击的按钮,而不是集中的按钮(因为集中操作不是单击操作)。选择的(猎人)答案是正确的。
Vasil Popov

我在提交按钮上有一个点击事件,并在其表单上提交事件...后者触发前者。我用它来找出事件的来源。在某些浏览器中,单击按钮会使按钮聚焦,而在其他浏览器中,您将一无所获。在我测试过的所有浏览器中,在输入时按Enter可使输入保持焦点。
notacouch 2015年

65

这对我有用:

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

3
这是有帮助的,拿到idactiveElement,我做了$(document.activeElement).attr('id');
Mikolaj

9
对于它的价值,您不需要使用jQuery来获取ID-使用纯Javascript甚至更简单:document.activeElement.id
Nick F

5
请注意,这似乎无法在Safari上正常工作。:(
rinogo

@rinogo:Safari中会发生什么?
新月新鲜

1
在Safari document.activeElement中不是输入。在我的情况下,它是一个模式div(包含表格)。
mgalgs 18-3-23

46

提交表单后:

  • document.activeElement 将为您提供单击的提交按钮。

  • document.activeElement.getAttribute('value') 将为您提供该按钮的价值。


2
请注意,这似乎无法在Safari上正常工作。:(
rinogo

我不知道Safari怎么样,但是在Chrome上效果很好:)谢谢!
格斯(Ingus)

适用于Chrome 63和IE11
Crispalot爵士,18年

我运行了jquery非侵入式验证,并且在此之前进行了拦截,并将无效输入设置为activeElement而不是按钮。
Peheje

28

这对我来说似乎更清洁。

首先,对于任何形式:

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

当为表单触发此click事件时,它仅记录原始目标(事件对象中可用),以供以后访问。这是一个相当大的笔划,因为它将在表单上的任何位置单击时触发。欢迎对优化发表评论,但我怀疑它永远不会引起明显的问题。

然后,在中$('form').submit(),您可以查询最后点击的内容,例如

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

如果这是一个表单提交事件而不是单击该怎么办?
托尼

1
@Tony,对不起,我没有很快看到您的问题。这个答案完全与表格提交有关。提交按钮也被单击,因此它们触发了click事件。
乔纳森·卡米尼施

2
由于在所有子元素单击事件之前触发了表单的Submit事件,因此建议在猎人的答案上使用此答案。当使用取消您的表单的Submit事件时,这会带来困难return false,而此方法可以正常工作,因为单击是绑定到表单而不是表单的子级。
pospi 2013年

7
这无法正确处理通过单击(例如,按Enter)以外的其他方式提交表单的情况。通过其他方式提交表单时,触发提交事件的是第一个提交按钮,而不是最后单击的那个按钮。
quietmint

此后缺少分号,... $(event.target))但无法编辑,因为编辑必须大于6个字符
Hafenkranich 2015年

13

哇,有些解决方案可能会变得复杂!如果您不介意使用简单的全局变量,则只需利用输入按钮click事件首先触发的事实即可。可以通过使用$('#myForm input')进一步过滤$('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总是那么困难。感谢那。要检查我何时回家
Thomas Williams


在Safari中,这不适用于我。单击正文中的按钮上的侦听器,将在表单上调用.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提交表单。

我也使用了“名称”属性而不是“ id”,但这是相同的方法。

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

因此,如果您使用TAB键将焦点移到第二个按钮上,然后按RETURN键,则默认为第一个按钮...
FrancescoMM


4

如果您不希望添加.click事件的意思是您不想为这些事件使用单独的处理程序,则可以在一个函数中处理所有点击(提交):

$(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 2011年

@hawk是的,应该。我不知道这是否是所需的行为,但是您的代码实际上并未提交表单,因此我的也没有。如果您确实要提交,则只需删除event.preventDefault或做类似的操作即可input.parents("form")[0].submit()
jcane86

而且,如果您不单击即可提交(返回键?),那将是一团糟
FrancescoMM

4

由于我无法对已接受的答案发表评论,因此我带来了一个修改后的版本,该版本应考虑表单之外的元素(即:使用form属性附加到表单上)。这是针对现代浏览器的:http : //caniuse.com/#feat=form-attribute。将closest('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但并非所有按钮都是提交按钮,这取决于它们的类型。
ptyskju

是的,但是在没有<input type =“ submit”>]的情况下,我曾经使用过的每个UA都将<button>标记视为表单提交触发器,因此可以解决这种情况。或者,作者可以添加一个警告,即所有具有提交功能的元素必须具有[type = submit]属性...另一个属性。
威尔

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中不起作用。注意:firefox现在需要一个隐藏字段,因为如果在on-submit事件中与jquery的this.submit()一起发送,它可能不会发送单击的提交值。我只是担心$(this).attr('name')可能不适用于所有浏览器。
user1610743

我拥有Firefox 30 / Windows7。一切正常。
anydasa 2014年

请记住包括button[type=submit]input[type=image]
rybo111

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-js在通过JavaScript提交的所有表单上添加了该类。


2

类似于Stan的答案,但:

  • 如果您有多个按钮,则只需获得第一个按钮=> [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>


接下来,在表单中按钮的click事件上,将CSS类添加到按钮。如果按钮已经具有CSS类,则将其删除。(我们不希望有两个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,则另一个按钮将具有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

您应该删除对样式和CSS的引用-它们与此处无关。另外,您使用hasClass()和的行removeClass()是多余的,因为addClass()不会两次添加相同的类。
rybo111

0

您可以创建输入type =“ hidden”作为按钮ID信息的持有人。

<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是在提交(?)之前发生的,这是可行的,但我不确定是否总是如此。


0

区分按下哪个<button>或<input type =“ button” ...>的简单方法是检查它们的'id':

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

0

这是一个示例,该示例使用this.form来获取提交所要进入的正确表单,并使用数据字段来存储最后单击/重点突出的元素。我还将提交代码包装在超时中,以确保单击事件在执行之前发生(某些用户在评论中报告说,在Chrome上,有时在提交后会触发单击事件)。

在使用键和鼠标/手指导航时都可以使用,而无需依靠浏览器在RETURN键上发送单击事件(虽然没有问题),我为按钮和字段的焦点事件添加了一个事件处理程序。

您可以将类型为“ 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>

哑巴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 2012年

1
这似乎不适用于提交按钮,window.event.srcElement返回表单的ID。
333Mhz 2013年

@KrzysztofCygan您有任何来源吗?
vard 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.