我如何从表单提交事件中获取导致提交的按钮?


110

我正在尝试查找触发表单提交的“提交”按钮的值

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

});

我可以为每个按钮触发$(“ input [type = submit]”)。click()事件并设置一些变量,但这似乎不如提交时将按钮从表单中拉出的方式那么优雅。


2
请注意,不一定有任何这样的按钮。脚本可以做到formobj.submit()。我认为点击事件是解决之道。
杰森·奥伦多夫

1
对于现代浏览器,现在event.submitter提供了单击<button>或的功能<input type="submit">
gfv

Answers:


107

我利用document.activeElement了此答案中所概述的内容:如何使用jQuery获取焦点元素?

$form.on('submit', function() {
    var $btn = $(document.activeElement);

    if (
        /* there is an activeElement at all */
        $btn.length &&

        /* it's a child of the form */ 
        $form.has($btn) &&

        /* it's really a submit element */
        $btn.is('button[type="submit"], input[type="submit"], input[type="image"]') &&

        /* it has a "name" attribute */
        $btn.is('[name]')
    ) {
        console.log("Seems, that this element was clicked:", $btn);
        /* access $btn.attr("name") and $btn.val() for data */
    }
});

我利用了一个事实,即单击按钮后按钮始终是焦点元素。如果单击后立即执行操作,则将无法使用blur()

@Doin发现了另一个缺点。如果用户enter在文本字段中通过提交表单,document.activeElement则不会设置。您需要通过处理类似keypress事件来自己input[type="text"]当心。

2017年1月更新:对于我的图书馆Hyperform,我选择不使用activeElement而是捕获所有导致表单提交的事件。此代码在Github上。

如果您碰巧使用Hyperform,则可以通过以下方式触发触发提交的按钮:

$(form).on('submit', function(event) {
  var button = event.submittedVia;
});

1
MDN同意。(FF3,IE4,Chrome 2,Safari 4,Opera 9)
Boldewyn14年

1
这应该是答案。
罗伊·纳米尔

2
嗯...如果通过[Enter]将表格加总,这行得通吗?Spec说应该等同于单击默认的提交按钮,但是我不确定它是否将其保留为活动元素。
Doin 2014年

8
可悲的是,您不能仅依赖activeElement,因为可以定义“提交者”:A.通过可靠的单击激活(直接用鼠标或键盘单击Space / Enter来单击);B.通过合成点击激活buttonElement.click()buttonElement.dispatch(new MouseEvent(...)),没有获得焦点);C.通过表单隐式提交(与其他表单的字段进行键盘交互)D.在formElement.submit()
mems

5
只是为了使事情保持最新状态的注释。截至目前,Safari在单击“提交”按钮时将activeElement设置为文档主体。我在Safari 9.1上遇到了这个问题
-coderkevin

35

我实现了这一点,我想它会做到的。

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

感谢您的回复,但这并不是非常优雅的...


1
不能跨浏览器/具有多个提交按钮功能。
user1610743 2014年

2
是否可以确保在表单提交事件之前触发click事件?我建议给表单一个doNotSubmit类,在Submit函数中检查该类是否不存在(否则不提交),在click事件中删除表单类doNotSubmit并执行$(''。myForm')。trigger ('提交'); 在将提交按钮值添加为隐藏字段之后
Hafenkranich

2
@Hafenkranich在极少数情况下,Chrome上的click事件是在Submit事件之后触发的。
romanoza

@roamnoza多数民众赞成在我也遇到了。
Hafenkranich '16

2
@ j4k3有更好的解决方案吗?这个答案是8岁
猎人

10

我创建了一个测试表单,并使用Firebug以这种方式获得了价值。

$('form').submit(function(event){
  alert(event.originalEvent.explicitOriginalTarget.value);
}); 

不幸的是,只有Firefox支持此事件。


5
IE没有此属性(explicitOriginalTarget)
andres descalzo 2010年

1
好的旧版IE将其弄乱了,经过了Firebug,看不到要使用的其他任何对象值,但完全忘记了其他浏览器。听到这样的消息并不奇怪,您将不得不检查Chrome。
Dave Anderson)2010年

11
仅Firefox支持此事件。
Andy E

因此,基本上,HTML中有些内容无法在JS中完成... Mozilla决定实现缺少的功能,没有人效仿吗?这就是为什么我们不能有好东西
aross

6

对于我来说,这是一种看起来更干净的方法。

首先,对于任何形式:

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

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

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

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

6

现在submitter,submit事件中有一个标准属性。
已在Firefox 75中实现

document.addEventListener('submit',function(e){
    console.log(e.submitter)
})

对于不支持它的浏览器,请使用以下polyfill

!function(){
    var lastBtn = null
    document.addEventListener('click',function(e){
        if (!e.target.closest) return;
        lastBtn = e.target.closest('button, input[type=submit]');
    }, true);
    document.addEventListener('submit',function(e){
        if ('submitter' in e) return;
        var canditates = [document.activeElement, lastBtn];
        for (var i=0; i < canditates.length; i++) {
            var candidate = canditates[i];
            if (!candidate) continue;
            if (!candidate.form) continue;
            if (!candidate.matches('button, input[type=button], input[type=image]')) continue;
            e.submitter = candidate;
            return;
        }
        e.submitter = e.target.querySelector('button, input[type=button], input[type=image]')
    }, true);
}();

4

根据此链接,事件对象包含一个字段Event.target,该字段:

返回表示启动事件的对象的字符串。

我刚刚创建了一个页面,测试了该值是什么,并且看起来该表示形式是针对表单本身的,而不是针对所单击按钮的。换句话说,Javascript不提供确定单击按钮的功能。

就Dave Anderson的解决方案而言,在使用它之前,最好在多个浏览器中对其进行测试。它可能可以正常工作,但我不能说任何一种方式。


1
target返回整个表格。因此,不幸的是,检测正确的提交按钮没有帮助。
Hafenkranich

我在回答中也说了很多,@ Hafenkranich。
cmptrgeekken '16

Event.target不是字符串。它是一个EventTarget对象,在这种情况下是提交的表单本身。
Akseli

4

一种干净的方法是在每个表单按钮上使用click事件。以下是带有保存,取消和删除按钮的html表单:

<form  name="formname" action="/location/form_action" method="POST">
<input name="note_id" value="some value"/>
<input class="savenote" type="submit" value="Save"/>
<input class="cancelnote" type="submit" value="Cancel"/>
<input class="deletenote" type="submit" value="Delete" />
</form> 

以下是jQuery。我将适当的“操作”发送到同一服务器功能,具体取决于单击的按钮(“保存”或“删除”)。如果单击“取消”,我将重新加载页面。

$('.savenote').click(function(){
   var options = {
       data: {'action':'save'}
   };
   $(this).parent().ajaxSubmit(options);
   });


$('.deletenote').click(function(){
   var options = {
       data: {'action':'delete'}
   };
   $(this).parent().ajaxSubmit(options);
   });


$('.cancelnote').click(function(){
   window.location.reload(true);
   return false;
   });

3

我搜索并找到了几种使用jQuery + AJAX 将提交按钮name+ value发送到服务器的方法。我不是很喜欢他们...

最好的之一是这里介绍的猎人解决方案!

但是我自己写了另一个。

我想分享一下,因为它很好,并且根据需要,它还可以通过ajax加载表单(在document.ready之后):

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

简单!单击提交按钮后,将使用表单name和提交按钮将一个隐藏字段添加到表单value

编辑:下面的版本更容易阅读。此外,它还要注意删除以前附加的隐藏字段(在两次提交相同表单的情况下,使用AJAX完全可以做到)。

改进的代码:

$(document).on('click', 'form input[type=submit]', function(){
    var name   = $(this).attr('name');
    if (typeof name == 'undefined') return;
    var value  = $(this).attr('value');
    var $form  = $(this).parents('form').first();
    var $input = $('<input type="hidden" class="temp-hidden" />').attr('name', name).attr('value', value);
    $form.find('input.temp-hidden').remove();
    $form.append($input);
});

1+这对我有用。谢谢!
Lennart Rolland 2012年

看起来这依赖于所有<button/>共享相同name属性的。我将使用一个类,并在您的文章中引用它.remove()
binki 2013年

@binki:不,不是。无论如何,每个开发人员都可以根据自己的需求调整解决方案。
J. Bruni

jsfiddle.net/binki/d8ecv展示了我关于name属性的意思。如果表单被重用并且包含具有不同名称的提交输入,则旧输入可能会使表单混乱。
binki 2013年

现在我看到了...我将更新我的答案。(实际上,由于您提到了<button/>元素,而我<input type="submit" />在代码中使用了这个事实,因此我没有过多注意您的评论)
J. Bruni

2

我确实尝试了所提供的一些示例,但是它们并没有达到我们的目的。

这是要显示的小提琴:http : //jsfiddle.net/7a8qhofo/1/

我遇到了类似的问题,这就是我们以表格形式解决问题的方式。

$(document).ready(function(){

    // Set a variable, we will fill later.
    var value = null;

    // On submit click, set the value
    $('input[type="submit"]').click(function(){
        value = $(this).val();
    });

    // On data-type submit click, set the value
    $('input[type="submit"][data-type]').click(function(){
        value = $(this).data('type');
    });

    // Use the set value in the submit function
    $('form').submit(function (event){
        event.preventDefault();
        alert(value);
        // do whatever you need to with the content
    });
});

2

(事件)

function submForm(form,event){
             var submitButton;

             if(typeof event.explicitOriginalTarget != 'undefined'){  //
                 submitButton = event.explicitOriginalTarget;
             }else if(typeof document.activeElement.value != 'undefined'){  // IE
                 submitButton = document.activeElement;
             };

             alert(submitButton.name+' = '+submitButton.value)
}


<form action="" method="post" onSubmit="submForm(this, event); return false;">

1

您可以使用“ event.originalEvent.x”和“ event.originalEvent.y”尝试这种方式:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
    <title>test</title>
</head>
<body>

    <form id="is_a_form">
        <input id="is_a_input_1" type="submit"><br />
        <input id="is_a_input_2" type="submit"><br />
        <input id="is_a_input_3" type="submit"><br />
        <input id="is_a_input_4" type="submit"><br />
        <input id="is_a_input_5" type="submit"><br />
    </form>

</body>
</html>
<script>
$(function(){

    $.fn.extend({
      inPosition: function(x, y) {

        return this.each(function() {

            try{
                var offset = $(this).offset();

                if ( (x >= offset.left) &&
                     (x <= (offset.left+$(this).width())) &&
                     (y >= offset.top) &&
                     (y <= (offset.top+$(this).height())) )
                {
                    $(this).css("background-color", "red");
                }
                else
                {
                        $(this).css("background-color", "#d4d0c8");
                }
                }
                catch(ex)
                {
                }

        });
      }
    }); 

    $("form").submit(function(ev) {

        $("input[type='submit']").inPosition(ev.originalEvent.x ,ev.originalEvent.y);
        return false;

    });

});
</script>

“ yikes” ?,它有用,它不起作用,它有用,没有用处,……?,我不能够讲好英语
安德烈斯descalzo

@hunter我如何多次评论您的评论?
汤姆·奥格

0

jQuery似乎不提供有关Submit事件的数据。看来您建议的方法是最好的选择。


0

另一个解决方案,因为没有其他解决方案可以满足我的要求。好处是,可以检测到单击和按键(输入和空格)

// Detects the Events
var $form = $('form');
$form.on('click keypress', 'button[type="submit"]', function (ev) {

    // Get the key (enter, space or mouse) which was pressed.
    if (ev.which === 13 || ev.which === 32 || ev.type === 'click') {

        // Get the clicked button
        var caller = ev.currentTarget;

        // Input Validation
        if (!($form.valid())) {
            return;
        }

        // Do whatever you want, e.g. ajax...
        ev.preventDefault();
        $.ajax({
            // ...
        })
    }
}

这对我来说效果最好。


0

使用更特定的事件处理程序和JQuery,您的事件对象就是单击的按钮。如果需要,您还可以从此事件获取委托表格。

$('form').on('click', 'button', function (e) {
  e.preventDefault();
  var
    $button = $(e.target),
    $form = $(e.delegateTarget);
  var buttonValue = $button.val();
});

此文档包含您入门所需的一切。 jQuery文档


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"));
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.