Làm cách nào tôi có thể nhận được nút đã gây ra gửi từ sự kiện gửi biểu mẫu?


110

Tôi đang cố gắng tìm giá trị của nút gửi đã kích hoạt biểu mẫu để gửi

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

});

Tôi có thể kích hoạt sự kiện $ ("input [type = submit]"). Click () cho mỗi nút và đặt một số biến, nhưng điều đó có vẻ kém thanh lịch hơn một số cách kéo nút ra khỏi biểu mẫu khi gửi.


2
Lưu ý rằng không nhất thiết phải có bất kỳ nút nào như vậy. Một tập lệnh có thể làm được formobj.submit(). Tôi nghĩ rằng các sự kiện nhấp chuột là con đường để đi.
Jason Orendorff

1
Đối với các trình duyệt hiện đại, bây giờ event.submittercó cung cấp cho bạn <button>hoặc <input type="submit">đã được nhấp vào.
gfv

Câu trả lời:


107

Tôi đã tận dụng document.activeElementnhư được phác thảo trong câu trả lời này: Làm thế nào để lấy phần tử tập trung với 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 */
    }
});

Tôi tận dụng lợi thế của thực tế, rằng nút luôn là yếu tố được chú trọng sau khi nhấp vào nó. Điều này sẽ không hoạt động, nếu bạn thực hiện blur()ngay sau khi nhấp chuột.

@Doin đã phát hiện ra một nhược điểm khác. Nếu người dùng gửi biểu mẫu qua entertrong trường văn bản, thì biểu mẫu document.activeElementkhông được đặt. Bạn cần phải tự mình đề phòng điều này, bằng cách xử lý keypresscác sự kiện trong input[type="text"]và tương tự.

Cập nhật 2017-01: Đối với Hyperform thư viện của tôi, tôi đã chọn không sử dụng activeElementnhưng để bắt tất cả các sự kiện dẫn đến gửi biểu mẫu. Mã cho điều này là trên Github.

Nếu bạn tình cờ sử dụng Hyperform, đây là cách bạn sẽ truy cập vào nút đã kích hoạt gửi:

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

1
MDN nói có. (FF3, IE4, Chrome 2, Safari 4, Opera 9)
Boldewyn

1
Đây nên là câu trả lời.
Royi Namir

2
Hmmm ... điều này có hoạt động nếu biểu mẫu được chèn qua [Enter]? Spec nói rằng điều đó sẽ tương đương với việc nhấp vào nút gửi mặc định, nhưng tôi không chắc nó có để nó làm phần tử hoạt động hay không.
Doin

8
Đáng buồn thay, bạn không thể chỉ dựa vàoactiveElement , vì "người gửi" có thể được định nghĩa: A. Thông qua kích hoạt nhấp chuột xác thực (nhấp trực tiếp bằng chuột hoặc bàn phím Space / Enter); B. Thông qua kích hoạt nhấp chuột tổng hợp ( buttonElement.click()hoặc buttonElement.dispatch(new MouseEvent(...)), không cần quan sát tiêu điểm); C. qua hình thức ngầm submittion (tương tác bàn phím với lĩnh vực hình thức khác) D. không ai sánh kịp, khiformElement.submit()
mems

5
Chỉ cần một ghi chú để giữ cho mọi thứ hiện tại. Hiện tại, Safari đặt activeElement vào nội dung tài liệu khi nhấp vào nút gửi. Tôi gặp sự cố này trên Safari 9.1
coderkevin

35

Tôi đã thực hiện điều này và tôi cho rằng nó sẽ thành công.

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

    var val = $("input[type=submit][clicked=true]").val()

    // DO WORK

});

và đây là sự kiện nút gửi thiết lập nó

$("form input[type=submit]").click(function() {
    $("input[type=submit]", $(this).parents("form")).removeAttr("clicked");
    $(this).attr("clicked", "true");
});

Cảm ơn vì những câu trả lời, nhưng điều này không quá khiếm nhã ...


1
Không có trình duyệt chéo / có nhiều nút gửi.
user1610743

2
Có đảm bảo rằng sự kiện nhấp chuột được kích hoạt trước sự kiện gửi biểu mẫu không? Tôi khuyên bạn nên cung cấp cho biểu mẫu một doNotSubmitlớp, bên trong hàm gửi kiểm tra xem lớp đó có tồn tại không (nếu không thì không gửi), bên trong sự kiện nhấp chuột, hãy xóa lớp biểu mẫu doNotSubmitvà thực hiện kích hoạt $ (''. MyForm '). ('Gửi đi'); sau khi thêm nộp giá trị nút như một lĩnh vực tiềm ẩn
Hafenkranich

2
@Hafenkranich Trong một số trường hợp hiếm hoi trên Chrome, sự kiện nhấp chuột được kích hoạt SAU sự kiện gửi.
romanoza,

@roamnoza đó chính xác là những gì tôi gặp phải.
Hafenkranich

2
@ j4k3 Bạn có giải pháp tốt hơn không? Câu trả lời này là 8 tuổi
thợ săn

10

Tôi đã tạo một biểu mẫu thử nghiệm và sử dụng Firebug đã tìm thấy cách này để nhận giá trị;

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

Thật không may, chỉ có Firefox hỗ trợ sự kiện này.


5
IE không có tài sản này (explicitOriginalTarget)
descalzo andres

1
IE cũ tốt làm nó rối tung lên, đã xem qua Firebug và không thể thấy bất kỳ giá trị đối tượng nào khác để sử dụng nhưng lại quên mất các trình duyệt thay thế. Tuy nhiên, không ngạc nhiên khi biết điều đó không xảy ra, bạn sẽ phải kiểm tra Chrome.
Dave Anderson

11
Chỉ Firefox hỗ trợ sự kiện này.
Andy E

Vì vậy, về cơ bản, có điều gì đó trong HTML không thể được thực hiện trong JS ... Mozilla quyết định triển khai tính năng còn thiếu và không ai làm theo? Đây là lý do tại sao chúng ta không thể có những điều tốt đẹp
aross

6

Đây là một cách tiếp cận có vẻ sạch hơn cho các mục đích của tôi.

Đầu tiên, đối với bất kỳ và tất cả các hình thức:

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

Khi sự kiện nhấp chuột này được kích hoạt cho một biểu mẫu, nó chỉ cần ghi lại đích gốc (có sẵn trong đối tượng sự kiện) để được truy cập sau này. Đây là một nét khá rộng, vì nó sẽ kích hoạt cho bất kỳ nhấp chuột nào ở bất kỳ đâu trên biểu mẫu. Nhận xét về tối ưu hóa được hoan nghênh, nhưng tôi nghi ngờ nó sẽ không bao giờ gây ra các vấn đề đáng chú ý.

Sau đó, trong $ ('form'). Submit (), bạn có thể hỏi những gì được nhấp lần cuối, với một cái gì đó như

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

6

Hiện có một submitterthuộc tính tiêu chuẩn trong sự kiện gửi.
Đã được triển khai trong Firefox 75 !

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

Đối với các trình duyệt không hỗ trợ nó, hãy sử dụng polyfill này :

!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

Theo liên kết này , đối tượng Sự kiện chứa một trường Event.target:

Trả về một chuỗi đại diện cho đối tượng đã bắt đầu sự kiện.

Tôi vừa tạo một trang để kiểm tra giá trị đó là gì, và nó xuất hiện như thể biểu diễn đó dành cho chính biểu mẫu, không phải cho nút được nhấp. Nói cách khác, Javascript không cung cấp cơ sở để xác định nút được nhấp.

Theo như giải pháp của Dave Anderson , có thể là một ý kiến ​​hay khi kiểm tra nó trên nhiều trình duyệt trước khi sử dụng nó. Có thể là nó có thể hoạt động tốt, nhưng tôi không thể nói theo cách nào.


1
Trả targetvề toàn bộ biểu mẫu. Vì vậy, rất tiếc là không hữu ích để phát hiện đúng nút gửi.
Hafenkranich

Tôi nói nhiều như vậy trong câu trả lời của mình, @Hafenkranich.
cmptrgeekken

Event.targetkhông phải là một chuỗi. Đó là một EventTargetđối tượng, trong trường hợp này là chính biểu mẫu đã gửi.
Akseli

4

Một cách tiếp cận rõ ràng là sử dụng sự kiện nhấp chuột trên mỗi nút biểu mẫu. Sau đây là một biểu mẫu html với các nút lưu, hủy và xóa:

<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> 

Sau đây là jquery. Tôi gửi 'hành động' thích hợp đến cùng một chức năng máy chủ tùy thuộc vào nút nào được nhấp vào ('lưu' hoặc 'xóa'). Nếu 'hủy bỏ', được nhấp vào, tôi chỉ cần tải lại trang.

$('.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

Tôi đã tìm kiếm và tìm thấy một số cách để lấy nút gửi name+ valueđược gửi đến máy chủ bằng jQuery + AJAX. Tôi không thích chúng cho lắm ...

Một trong những giải pháp tốt nhất là giải pháp của thợ săn được trình bày ở đây!

Nhưng tôi đã tự viết một cái khác.

Tôi muốn chia sẻ, bởi vì nó tốt và khi tôi cần, nó cũng hoạt động với các biểu mẫu được tải qua ajax (sau 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'));
});

Đơn giản! Khi nhấp vào nút gửi, một trường ẩn sẽ được thêm vào biểu mẫu, sử dụng cùng namevaluecủa nút gửi.

CHỈNH SỬA: Phiên bản dưới đây dễ đọc hơn. Ngoài ra, nó sẽ xử lý loại bỏ các trường ẩn đã thêm trước đó (trong trường hợp gửi cùng một biểu mẫu hai lần, điều này hoàn toàn có thể thực hiện được khi sử dụng AJAX).

Cải tiến mã:

$(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+ Điều này đã làm điều đó cho tôi. Cảm ơn!
Lennart Rolland

Có vẻ như điều này dựa trên việc tất cả các <button/>s chia sẻ cùng một namethuộc tính. Tôi sẽ sử dụng một lớp học và tham khảo đó trong của bạn .remove().
binki

@binki: không, nó không. Dù sao, mỗi nhà phát triển có thể điều chỉnh giải pháp theo nhu cầu của riêng mình.
J. Bruni

jsfiddle.net/binki/d8ecv cho biết ý tôi liên quan đến namethuộc tính. Nếu biểu mẫu được sử dụng lại và chứa các đầu vào gửi với các tên khác nhau, các đầu vào cũ có thể làm lộn xộn biểu mẫu.
binki

Bây giờ tôi thấy ... Tôi sẽ cập nhật câu trả lời của tôi. (Trong thực tế, tôi không quan tâm nhiều đến nhận xét của bạn do thực tế không liên quan mà bạn đề cập đến các <button/>yếu tố, trong khi <input type="submit" />được sử dụng trong các mã ...)
J. Bruni

2

Tôi đã thử một số ví dụ được cung cấp, nhưng chúng không hoạt động cho mục đích của chúng tôi.

Đây là một trò đùa để hiển thị: http://jsfiddle.net/7a8qhofo/1/

Tôi đã phải đối mặt với một vấn đề tương tự và đây là cách chúng tôi giải quyết vấn đề trong các biểu mẫu của mình.

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

( biến cố )

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

bạn có thể thử theo cách này với "event.originalEvent.x" và "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" ?, nó hoạt động, nó không hoạt động, nó hữu ích, không hữu ích, ...? , Tôi không nói được tiếng Anh tốt
descalzo andres

@hunter làm cách nào để tôi tán thành nhận xét của bạn nhiều lần?
Tom Auger

0

jQuery dường như không cung cấp dữ liệu đó về sự kiện gửi. Có vẻ như phương pháp bạn đề xuất là đặt cược tốt nhất của bạn.


0

Chỉ là một giải pháp khác vì không có giải pháp nào khác đáp ứng yêu cầu của tôi. Ưu điểm là, nhấp chuột và nhấn phím (nhập và dấu cách) được phát hiện.

// 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({
            // ...
        })
    }
}

Điều này làm việc tốt nhất cho tôi.


0

Với trình xử lý sự kiện cụ thể hơn và JQuery, đối tượng sự kiện của bạn là nút được nhấp. Bạn cũng có thể nhận được biểu mẫu ủy quyền từ sự kiện này nếu cần.

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

Tài liệu này có mọi thứ bạn cần để bắt đầu. Tài liệu JQuery .


0

Tôi viết hàm này giúp tôi

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;

};

và sau đó Sử dụng

var data= PupulateFormData($("form"));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.