Form gönderme olayından gönderime neden olan düğmeyi nasıl alabilirim?


110

Formu göndermeye tetikleyen gönder düğmesinin değerini bulmaya çalışıyorum

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

});

Muhtemelen bir $ ("input [type = submit]") tetikleyebilirim. Her düğme için tıklama () olayını ayarlayabilir ve bazı değişkenler ayarlayabilirim, ancak bu, gönderme sırasında düğmeyi formdan çekmekten daha az zarif görünüyor.


2
Mutlaka böyle bir düğme olmadığını unutmayın. Bir senaryo işe yarayabilir formobj.submit(). Bence tıklama etkinlikleri gitmenin yolu.
Jason Orendorff

1
Modern tarayıcılar için artık event.submittersize tıklanan <button>veya <input type="submit">tıklananları veren var.
gfv

Yanıtlar:


107

document.activeElementBu yanıtta çizildiği gibi kaldıraç kullandım: Odaklanılan öğeyi jQuery ile nasıl elde edebilirim?

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

Düğmenin, tıkladıktan sonra her zaman odaklanan öğe olması gerçeğinden yararlanıyorum. Bu olacak değil bir yaparsanız, işe blur()tıklamadan sonra sağa.

@Doin başka bir dezavantaj gördü. Bir kullanıcı formu enterbir metin alanında gönderirse, document.activeElementayarlanmaz. keypressOlayları input[type="text"]ve benzeri şeyleri ele alarak buna kendiniz dikkat etmeniz gerekir .

2017-01 Güncellemesi: Kütüphanem için Hyperform'u kullanmayı activeElementdeğil, form gönderimine neden olan tüm olayları yakalamayı seçtim . Bunun kodu Github'da.

Hyperform kullanıyorsanız, göndermeyi tetikleyen düğmeye şu şekilde erişirsiniz:

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

1
MDN evet diyor. (FF3, IE4, Chrome 2, Safari 4, Opera 9)
Boldewyn

1
Cevap bu olmalı.
Royi Namir

2
Hmmm ... form [Enter] aracılığıyla yazılırsa bu çalışır mı? Spec, bunun varsayılan gönder düğmesine tıklamaya eşdeğer olması gerektiğini söylüyor, ancak bunu etkin öğe olarak bırakıp bırakmadığından emin değilim.
Doin

8
Ne yazık ki, yalnızcaactiveElement "gönderen" tanımlanabildiği için güvenemezsiniz : A. Gerçek tıklama aktivasyonu yoluyla (doğrudan fare veya klavye ile tıklanır Boşluk / Enter); B. Sentetik tıklama aktivasyonu yoluyla ( buttonElement.click()veya buttonElement.dispatch(new MouseEvent(...))odağı artırmadan); C. form aracılığıyla örtük olarak gönderme (diğer formun alanıyla klavye etkileşimi) D. hiçbirine, ne zamanformElement.submit()
2014

5
İşleri güncel tutmak için sadece bir not. Şu andan itibaren, Safari bir gönder düğmesine tıklandığında activeElement öğesini belge gövdesine ayarlıyor. Bu sorunla Safari 9.1'de karşılaştım
coderkevin

35

Bunu uyguladım ve sanırım işe yarayacak.

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

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

    // DO WORK

});

ve bu, onu oluşturan gönder düğmesi etkinliğidir

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

Cevaplar için teşekkürler, ama bu çok da uygunsuz değil ...


1
Tarayıcılar arası / birden çok gönderme düğmesi özelliği yoktur.
user1610743

2
Tıklama olayının form gönderme olayından önce tetiklenmesi garanti ediliyor mu? Forma bir doNotSubmitsınıf vermenizi öneririm , sınıf mevcut değilse gönder fonksiyonu kontrolünde (aksi takdirde göndermeyin), tıklama olayı içinde form sınıfını kaldırın doNotSubmitve bir $ (". MyForm ') tetikleyin. ('Sunmak'); Gönder düğmesi değerini gizli alan olarak ekledikten sonra
Hafenkranich

2
@Hafenkranich Chrome'da bazı nadir durumlarda, tıklama olayı gönderme olayından SONRA tetiklenir.
romanoza

@roamnoza da tam olarak karşılaştığım şey.
Hafenkranich

2
@ j4k3 Daha iyi bir çözümünüz var mı? Bu cevap 8 yaşında
avcı

10

Bir test formu oluşturdum ve Firebug kullanarak değeri almak için bu yolu buldum;

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

Ne yazık ki, yalnızca Firefox bu etkinliği desteklemektedir.


5
IE bu özelliğe sahip değil (explicitOriginalTarget)
andres descalzo

1
Eski güzel IE bunu mahvetti, Firebug'dan geçti ve kullanılacak diğer nesne değerlerini göremedi, ancak alternatif tarayıcıları unuttu. Yine de duyulmasına şaşırmadım, Chrome'u kontrol etmek zorunda kalacak.
Dave Anderson

11
Bu etkinliği yalnızca Firefox desteklemektedir.
Andy E

Yani temelde, HTML'de JS'de yapılamayan bir şey var ... Mozilla eksik özelliği uygulamaya karar verdi ve kimse onu takip etmedi mi? Bu yüzden güzel şeylere sahip
olamayız

7

Artık submittergönder etkinliğinde standart bir özellik var.
Firefox 75'te zaten uygulanmış !

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

Desteklemeyen tarayıcılar için şu çoklu dolguyu kullanın :

!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

İşte amaçlarım için daha temiz görünen bir yaklaşım.

İlk olarak, her türlü form için:

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

Bu tıklama olayı bir form için tetiklendiğinde, daha sonra erişilmek üzere kaynak hedefi (olay nesnesinde bulunan) kaydeder. Bu oldukça geniş bir vuruş, çünkü formun herhangi bir yerinde herhangi bir tıklama için tetiklenecek. Optimizasyon yorumları memnuniyetle karşılanır, ancak bunun hiçbir zaman gözle görülür sorunlara neden olmayacağından şüpheleniyorum.

Daha sonra, $ ['form']. Submit () 'da, en son neyin tıklandığını sorgulayabilirsiniz.

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

4

Bu bağlantıya göre , Event nesnesi bir alan içerirEvent.target şunları :

Olayı başlatan nesneyi temsil eden bir dize döndürür.

Bu değerin ne olduğunu test eden bir sayfa oluşturdum ve bu temsil, tıklanan düğme için değil, formun kendisi içinmiş gibi görünüyor. Başka bir deyişle, Javascript tıklanan düğmeyi belirleme olanağı sağlamaz.

Dave Anderson'ın çözümüne gelince , bunu kullanmadan önce birden fazla tarayıcıda test etmek iyi bir fikir olabilir. İyi çalışması mümkün, ancak her iki şekilde de söyleyemem.


1
targetBütün dönersek. Bu nedenle maalesef doğru gönder butonunu tespit etmeye yardımcı olmuyor.
Hafenkranich

Cevabımda da aynısını söylüyorum @Hafenkranich.
cmptrgeekken

Event.targetbir dizge değil. Bu EventTarget, bu durumda gönderilen formun kendisidir.
Akseli

4

Temiz bir yaklaşım, her form düğmesinde tıklama olayını kullanmaktır. Aşağıda kaydet, iptal et ve sil düğmeleri olan bir html formu verilmiştir:

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

Aşağıdaki jquery. Hangi düğmenin tıklandığına bağlı olarak uygun 'eylemi' aynı sunucu işlevine gönderiyorum ('kaydet' veya 'sil'). 'İptal' tıklanırsa, sadece sayfayı yeniden yüklerim.

$('.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 kullanarak sunucuya gönder düğmesini name+ göndermenin birkaç yolunu araştırdım ve buldum value. Onlardan pek hoşlanmadım ...

En iyilerden biri, burada sunulan avcı çözümüydü!

Ama kendim bir tane daha yazdım.

Paylaşmak istiyorum çünkü iyi ve ihtiyaç duyduğumda ajax aracılığıyla yüklenen formlarla da çalışıyor (document.ready'nin ardından):

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

Basit! Gönder düğmesine tıklandığında, forma gizli bir alan eklenir nameve aynı vevalue gönder düğmesi .

DÜZENLE: Aşağıdaki sürümün okunması daha kolaydır. Ayrıca, önceden eklenen gizli alanların kaldırılmasıyla da ilgilenir (aynı formun iki kez gönderilmesi durumunda, bu AJAX kullanırken mükemmel şekilde mümkündür).

Geliştirilmiş kod:

$(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+ Bu benim için yaptı. Teşekkürler!
Lennart Rolland

Görünüşe göre bu, herkesin <button/>aynı nameözelliği paylaşmasına bağlı . Bir sınıf kullanırdım ve buna senin içinde atıfta bulunurdum .remove().
binki

@binki: hayır, öyle değil. Her neyse, her geliştirici çözümü kendi ihtiyaçlarına göre uyarlayabilir.
J. Bruni

jsfiddle.net/binki/d8ecv , nameöznitelikle ilgili ne demek istediğimi gösterir . Form yeniden kullanılırsa ve farklı adlara sahip gönderme girişleri içeriyorsa, eski girişler formu karmaşık hale getirebilir.
binki

Şimdi anlıyorum ... Cevabımı güncelleyeceğim. (Aslında, kodda kullanılırken <button/>öğeden bahsettiğiniz için yorumunuza fazla dikkat etmedim <input type="submit" />...)
J. Bruni

2

Verilen bazı örnekleri denedim, ancak amaçlarımız için işe yaramadılar.

İşte gösterilecek bir keman: http://jsfiddle.net/7a8qhofo/1/

Ben de benzer bir sorunla karşılaştım ve formlarımızda sorunu bu şekilde çözdük.

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

( Etkinlik )

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

bu yolu "event.originalEvent.x" ve "event.originalEvent.y" ile deneyebilirsiniz:

<!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" ?, işe yarıyor, çalışmıyor, yararlı, kullanışlı değil, ...? , İyi İngilizce konuşamıyorum
andres descalzo

@hunter yorumunuzu nasıl birden çok kez yükseltebilirim?
Tom Auger

0

jQuery, bu verileri gönderme olayında sağlamıyor gibi görünüyor. Görünüşe göre önerdiğiniz yöntem en iyi seçeneğiniz.


0

Gereksinimlerimi başka hiçbir şey karşılamadığı için başka bir çözüm. Bunun avantajı, tıklama ve tuşa basmanın (giriş ve boşluk) algılanmasıdır.

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

Bu benim için en iyisi oldu.


0

Daha spesifik bir olay işleyicisi ve JQuery ile, olay nesneniz tıklanan düğmedir. Gerekirse bu etkinlikten temsilci formunu da alabilirsiniz.

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

Bu Doküman, başlamak için ihtiyacınız olan her şeye sahiptir. JQuery Doc .


0

Bana yardımcı olan bu işlevi yazıyorum

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;

};

ve sonra Kullan

var data= PupulateFormData($("form"));

0

Formun SubmitEvent'i için bir gönderen özelliği var . Ancak, şu an itibariyle bu Safari'de çalışmıyor.

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

Tarayıcılarda çalışan farklı bir yaklaşım. Ancak, nesne formyerine öğeye güvenmelisiniz event. Bu, temel olarak form öğesi nesnesine, daha sonra form gönderimi sırasında başvurulabilecek bir "gönderen" özelliği ekler.

<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);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.