web-dev-qa-db-fra.com

Comment puis-je obtenir le bouton qui a provoqué l'envoi à partir de l'événement de soumission de formulaire?

J'essaie de trouver la valeur du bouton d'envoi qui a déclenché l'envoi du formulaire.

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

});

Je pourrais éventuellement déclencher un événement $ ("input [type = submit]"). Click () pour chaque bouton et définir une variable, mais cela semble moins élégant que de voir comment tirer le bouton du formulaire lors de son envoi.

97
hunter

J'ai implémenté ceci et je suppose que ça ira.

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

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

    // DO WORK

});

et c'est l'événement bouton de soumission qui le configure

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

Merci pour les réponses, mais ce n'est pas terriblement inélégant ...

33
hunter

J'ai exploité document.activeElement comme esquissé dans cette réponse: Comment obtenir l'élément ciblé avec 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 */
    }
});

Je profite du fait que le bouton est toujours l'élément ciblé après avoir cliqué dessus. Cela fonctionnera pas, si vous faites un blur() juste après le clic.

@Doin a repéré un autre inconvénient. Si un utilisateur soumet le formulaire via enter dans un champ de texte, le document.activeElement n'est pas défini. Vous devez faire attention à cela vous-même, en gérant les événements keypress dans input[type="text"] et similaire.

Mise à jour 2017-01: Pour ma bibliothèque Hyperform J'ai choisi de ne pas utiliser activeElement mais de capturer tous les événements menant à la soumission du formulaire. Le code pour cela est sur Github.

Si vous utilisez Hyperform, voici comment accéder au bouton qui a déclenché l'envoi:

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

J'ai créé un formulaire de test et en utilisant Firebug, j'ai trouvé ce moyen pour obtenir la valeur.

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

Malheureusement, seul Firefox prend en charge cet événement.

9
Dave Anderson

Voici une approche qui semble plus propre à mes fins.

Tout d'abord, pour toutes les formes:

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

Lorsque cet événement click est déclenché pour un formulaire, il enregistre simplement la cible d'origine (disponible dans l'objet événement) à laquelle accéder ultérieurement. C'est un trait assez large, car il se déclenchera pour n'importe quel clic n'importe où sur le formulaire. Les commentaires d'optimisation sont les bienvenus, mais je suppose que cela ne posera jamais de problème notable.

Ensuite, dans $ ('formulaire'). Submit (), vous pouvez demander ce qui a été cliqué en dernier, avec quelque chose comme

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

Une approche simple consiste à utiliser l'événement click sur chaque bouton de formulaire . Voici un formulaire HTML avec les boutons Enregistrer, Annuler et Supprimer:

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

Voici le jquery. J'envoie l'action appropriée à la même fonction du serveur en fonction du bouton sur lequel vous avez cliqué ("enregistrer" ou "supprimer"). Si vous cliquez sur «Annuler», je recharge simplement la page.

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

Selon ce lien , l’objet Event contient un champ Event.target, qui:

Retourne une chaîne représentant l'objet qui a initié l'événement.

Je viens de créer une page testant quelle est cette valeur, et il semble que cette représentation concerne le formulaire lui-même et non le bouton sur lequel vous avez cliqué. En d'autres termes, Javascript ne permet pas de déterminer le bouton cliqué.

En ce qui concerne la solution de Dave Anderson , il peut être judicieux de la tester dans plusieurs navigateurs avant de l’utiliser. Il est possible que cela fonctionne bien, mais je ne peux pas le dire.

4
cmptrgeekken

J'ai cherché et trouvé plusieurs façons d'obtenir le bouton de soumission name + value envoyé au serveur à l'aide de jQuery + AJAX. Je ne les ai pas beaucoup aimés ...

L'un des meilleurs atouts est la solution de chasseur présentée ici!

Mais j'en ai écrit un autre moi-même.

Je souhaite partager, car il est bon et, selon mes besoins, il fonctionne également avec les formulaires chargés via ajax (après 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'));
});

Simple! Lorsque le bouton de soumission est cliqué, un champ masqué est ajouté au formulaire, utilisant les mêmes name et value du bouton de soumission.

EDIT: La version ci-dessous est plus facile à lire. En outre, il s’occupe de supprimer les champs cachés précédemment ajoutés (dans le cas de soumettre le même formulaire deux fois, ce qui est parfaitement possible avec AJAX).

Code amélioré:

$(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);
});
3
J. Bruni

( un événement )

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;">
2
user3126867

J'ai essayé certains des exemples fournis, mais ils ne fonctionnaient pas pour notre propos.

Voici un violon à montrer: http://jsfiddle.net/7a8qhofo/1/

J'ai été confronté à un problème similaire, et voici comment nous avons résolu le problème dans nos formulaires. 

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

vous pouvez essayer de cette façon avec "event.originalEvent.x" et "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>
1
andres descalzo

jQuery ne semble pas fournir ces données sur l'événement submit. On dirait que la méthode que vous avez proposée est votre meilleur pari.

0
Matchu

Avec un gestionnaire d'événements plus spécifique et JQuery, votre objet événement est le bouton sur lequel vous avez cliqué. Vous pouvez également obtenir le formulaire de délégation de cet événement si nécessaire.

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

Ce Doc a tout ce dont vous avez besoin pour commencer . JQuery Doc .

0
user8205152

J'écris cette fonction qui m'aide

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;

};

et ensuite utiliser

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

Juste une autre solution, aucune autre ne répondant à mes exigences L'avantage est que click et appui sur la touche (entrée et espace) sont détectés.

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

Cela a fonctionné mieux pour moi.

0
roland