ฉันจะรับปุ่มที่ทำให้เกิดการส่งจากเหตุการณ์ส่งแบบฟอร์มได้อย่างไร


110

ฉันกำลังพยายามหาค่าของปุ่มส่งที่เรียกให้ส่งแบบฟอร์ม

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

});

ฉันอาจจะยิง $ ("input [type = submit]") คลิก () เหตุการณ์สำหรับแต่ละปุ่มและตั้งค่าตัวแปรบางอย่าง แต่ดูเหมือนจะไม่ค่อยหรูหรากว่าการดึงปุ่มออกจากแบบฟอร์มเมื่อส่ง


2
โปรดทราบว่าไม่จำเป็นต้องมีปุ่มดังกล่าว formobj.submit()สคริปต์อาจจะทำ ฉันคิดว่าเหตุการณ์คลิกเป็นวิธีที่จะไป
Jason Orendorff

1
สำหรับเบราว์เซอร์สมัยใหม่ขณะนี้มีevent.submitterให้คุณ<button>หรือ<input type="submit">ที่คลิก
gfv

คำตอบ:


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-01:สำหรับHyperformไลบรารีของฉันฉันเลือกที่จะไม่ใช้activeElementแต่เพื่อจับเหตุการณ์ทั้งหมดซึ่งนำไปสู่การส่งแบบฟอร์ม รหัสนี้อยู่ใน Github

หากคุณบังเอิญใช้ Hyperform นี่คือวิธีที่คุณจะเข้าถึงปุ่มที่เรียกการส่ง:

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

1
MDNบอกว่าใช่ (FF3, IE4, Chrome 2, Safari 4, Opera 9)
Boldewyn

1
นี่น่าจะเป็นคำตอบ
Royi Namir

2
อืม ... จะได้ผลไหมถ้าฟอร์มถูกรวมผ่าน [Enter]? Spec บอกว่าควรจะเทียบเท่ากับการคลิกปุ่มส่งเริ่มต้น แต่ฉันไม่แน่ใจว่าจะปล่อยให้เป็นองค์ประกอบที่ใช้งานอยู่หรือไม่
Doin

8
น่าเศร้าที่คุณไม่สามารถพึ่งพาเพียงอย่างเดียวได้activeElementเนื่องจาก "ผู้ส่ง" สามารถกำหนดได้: A. ผ่านการเปิดใช้งานการคลิกที่แท้จริง (คลิกโดยตรงด้วยเมาส์หรือแป้นพิมพ์ Space / Enter); B. ผ่านการเปิดใช้งานการคลิกแบบสังเคราะห์ ( buttonElement.click()หรือbuttonElement.dispatch(new MouseEvent(...))โดยไม่ต้องใช้โฟกัส) C. ผ่านแบบฟอร์มส่งโดยปริยาย (การโต้ตอบแป้นพิมพ์กับฟิลด์ของรูปแบบอื่น) ง. ถึงไม่มีเมื่อใดformElement.submit()
ส์

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

2
รับประกันได้หรือไม่ว่าเหตุการณ์การคลิกจะถูกทริกเกอร์ก่อนเหตุการณ์การส่งแบบฟอร์ม ฉันขอแนะนำให้ให้ฟอร์มdoNotSubmitคลาสภายในฟังก์ชัน submit ตรวจสอบว่าคลาสนั้นไม่มีอยู่จริงหรือไม่ (ไม่ต้องส่ง) ภายในเหตุการณ์คลิกให้ลบคลาสฟอร์มdoNotSubmitและทำ $ (''. myForm ') ทริกเกอร์ ('ส่ง'); หลังจากเพิ่มค่าปุ่มส่งเป็นฟิลด์ที่ซ่อน
Hafenkranich

2
@Hafenkranich ในบางโอกาสที่เกิดขึ้นได้ยากบน Chrome เหตุการณ์การคลิกจะถูกทริกเกอร์หลังจากส่งเหตุการณ์
romanoza

@roamnoza นั่นคือสิ่งที่ฉันเจอเช่นกัน
Hafenkranich

2
@ j4k3 มีทางออกที่ดีกว่านี้ไหม คำตอบนี้อายุ 8 ปี
นักล่า

10

ฉันสร้างแบบฟอร์มทดสอบและใช้ Firebug พบวิธีนี้เพื่อรับค่า

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

น่าเสียดายที่มีเพียง Firefox เท่านั้นที่รองรับกิจกรรมนี้


5
IE ไม่มีคุณสมบัตินี้ (ExplicitOriginalTarget)
andres descalzo

1
IE เก่าที่ดีทำให้ยุ่งเหยิงผ่าน Firebug และไม่เห็นค่าวัตถุอื่น ๆ ที่จะใช้ แต่ลืมไปเลยเกี่ยวกับเบราว์เซอร์ทางเลือก ไม่แปลกใจที่ไม่ได้ยิน แต่จะต้องตรวจสอบ Chrome
Dave Anderson

11
Firefox เท่านั้นที่รองรับกิจกรรมนี้
Andy E

โดยพื้นฐานแล้วมีบางอย่างใน HTML ที่ไม่สามารถทำได้ใน JS ... Mozilla ตัดสินใจที่จะใช้คุณลักษณะที่ขาดหายไปและไม่มีใครปฏิบัติตาม? นี่คือเหตุผลที่เราไม่สามารถมีสิ่งที่ดี
aross

7

ขณะนี้มีsubmitterคุณสมบัติมาตรฐานในเหตุการณ์ส่ง
ติดตั้งใน 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);
}();

6

นี่คือแนวทางที่ดูสะอาดกว่าสำหรับวัตถุประสงค์ของฉัน

ประการแรกสำหรับทุกรูปแบบ:

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

เมื่อเหตุการณ์การคลิกนี้เริ่มทำงานสำหรับแบบฟอร์มเพียงแค่บันทึกเป้าหมายต้นทาง (ที่มีอยู่ในวัตถุเหตุการณ์) ที่จะเข้าถึงได้ในภายหลัง นี่เป็นจังหวะที่ค่อนข้างกว้างเนื่องจากจะเริ่มทำงานเมื่อคลิกที่ใดก็ได้บนแบบฟอร์ม ยินดีต้อนรับความคิดเห็นเกี่ยวกับการเพิ่มประสิทธิภาพ แต่ฉันสงสัยว่าจะไม่ทำให้เกิดปัญหาที่สังเกตเห็นได้

จากนั้นใน $ ('form') ส่ง () คุณสามารถสอบถามว่าคลิกล่าสุดคืออะไร

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

4

ตามลิงค์นี้วัตถุเหตุการณ์มีฟิลด์Event.targetซึ่ง:

ส่งคืนสตริงที่แสดงถึงออบเจ็กต์ที่เริ่มต้นเหตุการณ์

ฉันเพิ่งสร้างเพจเพื่อทดสอบว่าค่านั้นคืออะไรและดูเหมือนว่าการแสดงนั้นเป็นของแบบฟอร์มเองไม่ใช่สำหรับปุ่มที่คลิก กล่าวอีกนัยหนึ่ง Javascript ไม่มีสิ่งอำนวยความสะดวกในการกำหนดปุ่มที่คลิก

สำหรับโซลูชันของ Dave Anderson อาจเป็นความคิดที่ดีที่จะทดสอบในเบราว์เซอร์หลายตัวก่อนใช้งาน เป็นไปได้ว่ามันจะทำงานได้ดี แต่ฉันไม่สามารถพูดอย่างใดอย่างหนึ่งได้


1
targetผลตอบแทนในรูปแบบทั้ง ดังนั้นจึงไม่เป็นประโยชน์ในการตรวจจับปุ่มส่งที่ถูกต้อง
Hafenkranich

ฉันพูดมากเท่าในคำตอบของฉัน @Hafenkranich
cmptrgeekken

Event.targetไม่ใช่สตริง เป็นEventTargetวัตถุซึ่งในกรณีนี้คือแบบฟอร์มที่ส่งมาเอง
Akseli

4

แนวทางหนึ่งที่สะอาดคือการใช้เหตุการณ์คลิกบนปุ่มฟอร์มแต่ละปุ่ม ต่อไปนี้เป็นรูปแบบ 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

ฉันค้นหาและพบหลายวิธีในการรับปุ่มส่งname+ valueส่งไปยังเซิร์ฟเวอร์โดยใช้ jQuery + AJAX ฉันไม่ชอบพวกเขามาก ...

หนึ่งในวิธีที่ดีที่สุดคือโซลูชันของนักล่าที่นำเสนอที่นี่!

แต่ฉันเขียนอีกอันหนึ่งด้วยตัวเอง

ฉันต้องการแบ่งปันเพราะมันดีและอย่างที่ฉันต้องการมันใช้งานได้กับแบบฟอร์มที่โหลดผ่าน 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

ดูเหมือนว่าสิ่งนี้จะอาศัย<button/>การแบ่งปันnameแอตทริบิวต์เดียวกันทั้งหมด ฉันจะใช้คลาสและอ้างถึงสิ่งนั้นใน.remove()ไฟล์.
binki

@binki: ไม่มันไม่ได้ อย่างไรก็ตามนักพัฒนาแต่ละคนสามารถปรับแก้ปัญหาให้เข้ากับความต้องการของตนเองได้
J. Bruni

jsfiddle.net/binki/d8ecvแสดงว่าฉันหมายถึงอะไรเกี่ยวกับnameแอตทริบิวต์ ถ้าแบบฟอร์มถูกนำมาใช้ซ้ำและมีอินพุตส่งที่มีชื่อต่างกันอินพุตเก่าอาจทำให้ฟอร์มยุ่งเหยิง
binki

ตอนนี้ฉันเห็น ... ฉันจะอัปเดตคำตอบของฉัน (อันที่จริงฉันไม่ได้ให้ความสนใจกับความคิดเห็นของคุณมากนักเนื่องจากไม่เกี่ยวข้องกับข้อเท็จจริงที่คุณพูดถึง<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"?, มันใช้งานได้, ไม่ได้ผล, มีประโยชน์, ไม่มีประโยชน์, ... ? ฉันพูดภาษาอังกฤษไม่เก่ง
andres descalzo

@hunter ฉันจะโหวตความคิดเห็นของคุณหลาย ๆ ครั้งได้อย่างไร?
Tom Auger

0

ดูเหมือนว่า jQuery จะไม่ให้ข้อมูลนั้นในการส่งเหตุการณ์ ดูเหมือนว่าวิธีที่คุณเสนอจะเป็นทางออกที่ดีที่สุดของคุณ


0

เป็นวิธีแก้ปัญหาอื่นเนื่องจากไม่มีวิธีอื่นตรงตามข้อกำหนดของฉัน ข้อดีคือตรวจพบการคลิกและการกดแป้น (Enter และเว้นวรรค)

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

0

มีความเป็นผู้ส่งคุณสมบัติสำหรับฟอร์มSubmitEvent อย่างไรก็ตามในปัจจุบันสิ่งนี้ใช้ไม่ได้กับ Safari

<form id="form">
    <button value="add" type="submit">Add</button>
    <button value="remove" type="submit">Remove</button>
</form>
let form = document.getElementById('form');

form.onsubmit = (event) => {
    e.preventDefault();
    console.log(e.submitter.type);
}

แนวทางอื่นที่ใช้ได้กับเบราว์เซอร์ อย่างไรก็ตามคุณต้องพึ่งพาformองค์ประกอบแทนeventวัตถุ โดยพื้นฐานแล้วจะเพิ่มคุณสมบัติ 'ผู้ส่ง' ลงในออบเจ็กต์องค์ประกอบฟอร์มที่สามารถอ้างอิงได้ในภายหลังในการส่งแบบฟอร์ม

<form id="form">
    <button onclick="this.form.submitter = 'add'" type="submit">Add</button>
    <button onclick="this.form.submitter = 'remove'" type="submit">Remove</button>
</form>
let form = document.getElementById('form');

form.onsubmit = (event) => {
    e.preventDefault();
    console.log(form.submitter);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.