it-swarm.com.de

jQuery: Wie erhält man die Schaltfläche, die beim Senden des Formulars angeklickt wurde?

Ich habe ein .submit()-Ereignis für die Formularübermittlung eingerichtet. Ich habe auch mehrere Formulare auf der Seite, aber hier nur eines für dieses Beispiel. Ich würde gerne wissen, auf welche Schaltfläche "Senden" geklickt wurde, ohne dass auf jedes Ereignis ein .click()-Ereignis angewendet wurde.

Hier ist das Setup:

<html>
<head>
  <title>jQuery research: forms</title>
  <script type='text/javascript' src='../jquery-1.5.2.min.js'></script>
  <script type='text/javascript' language='javascript'>
      $(document).ready(function(){
          $('form[name="testform"]').submit( function(event){ process_form_submission(event); } );
      });
      function process_form_submission( event ) {
          event.preventDefault();
          //var target = $(event.target);
          var me = event.currentTarget;
          var data = me.data.value;
          var which_button = '?';       // <-- this is what I want to know
          alert( 'data: ' + data + ', button: ' + which_button );
      }
  </script>
</head>
<body>
<h2>Here's my form:</h2>
<form action='nothing' method='post' name='testform'>
  <input type='hidden' name='data' value='blahdatayadda' />
  <input type='submit' name='name1' value='value1' />
  <input type='submit' name='name2' value='value2' />
</form>
</body>
</html>

Live-Beispiel zu jsfiddle

Gibt es neben der Anwendung eines .click () - Ereignisses auf jede Schaltfläche eine Möglichkeit, festzustellen, welche Übergabeschaltfläche angeklickt wurde?

191
hawkexp

Ich habe die gleiche Frage gestellt: Wie bekomme ich den Button, der das Senden verursacht hat, vom Formular zum Senden des Ereignisses?

Ich habe diese Lösung gefunden und sie hat gut funktioniert:

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

In Ihrem Fall mit mehreren Formularen müssen Sie dies möglicherweise etwas anpassen, es sollte jedoch immer noch zutreffen

212
hunter

Ich habe festgestellt, dass dies funktioniert hat.

$(document).ready(function() {
    $( "form" ).submit(function () {
        // Get the submit button element
        var btn = $(this).find("input[type=submit]:focus" );
    });
}
79
Stan

Das funktioniert für mich:

$("form").submit(function() {
   // Print the value of the button that was clicked
   console.log($(document.activeElement).val());
}
56
seddonym

Wenn das Formular übermittelt wird: 

  • document.activeElement gibt Ihnen die Schaltfläche "Senden", die angeklickt wurde.

  • document.activeElement.getAttribute('value') gibt Ihnen den Wert dieser Schaltfläche.

37
Nick F

Hier ist der Ansatz, der für meine Zwecke sauberer erscheint.

Erstens für alle Formen:

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

Wenn dieses Klickereignis für ein Formular ausgelöst wird, zeichnet es lediglich das Ursprungsziel (im Ereignisobjekt verfügbar) auf, auf das später zugegriffen werden kann. Dies ist ein ziemlich breiter Strich, da er bei jedem Klick auf das Formular ausgelöst wird. Optimierungskommentare sind willkommen, aber ich vermute, dass dies niemals zu merklichen Problemen führen wird.

Dann können Sie in $ ('form'). Submit () mit etwas Ähnlichem nach dem zuletzt angeklickten Element fragen

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

Wow, manche Lösungen können kompliziert werden! Wenn es Ihnen nichts ausmacht, ein einfaches globales Objekt zu verwenden, nutzen Sie einfach die Tatsache, dass das Klickereignis der Eingabeschaltfläche zuerst ausgelöst wird. Man könnte den $ ('input') - Selektor mit Hilfe von $ ('# myForm input') nach einer von vielen Formen filtern.

    $(document).ready(function(){
      var clkBtn = "";
      $('input[type="submit"]').click(function(evt) {
        clkBtn = evt.target.id;
      });

      $("#myForm").submit(function(evt) {
        var btnID = clkBtn;
        alert("form submitted; button id=" + btnID);
      });
    });
10
lawnbowler

Ich habe die beste Lösung gefunden

$(document.activeElement).attr('id')

Dies funktioniert nicht nur bei Eingängen, sondern auch bei Schaltflächen-Tags . Außerdem erhält es die ID der Schaltfläche.

7
Thomas Williams

Eine andere mögliche Lösung besteht darin, ein verstecktes Feld in Ihr Formular einzufügen:

<input type="hidden" id="btaction"/>

Fügen Sie dann in der Bereitschaftsfunktion Funktionen hinzu, um aufzuzeichnen, welche Taste gedrückt wurde:

$('form#myForm #btnSubmit').click(function() {
    $('form#myForm #btaction').val(0);
});

$('form#myForm #btnSubmitAndSend').click(function() {
    $('form#myForm #btaction').val(1);
});

$('form#myForm #btnDelete').click(function() {
    $('form#myForm #btaction').val(2);
});

Lesen Sie nun im Formular-Submition-Handler die verborgene Variable und entscheiden Sie basierend auf dieser:

var act = $('form#myForm #btaction').val();
6
wmac

Aufbauend auf dem, was Stan und yann-h getan haben, ist dieser standardmäßig auf die erste Schaltfläche eingestellt. Das Schöne an diesem Gesamtansatz ist, dass er sowohl die Klick- als auch die Eingabetaste aufnimmt (auch wenn der Fokus nicht auf der Schaltfläche lag. Wenn Sie die Eingabe im Formular zulassen müssen, dann reagieren Sie einfach darauf, wenn eine Schaltfläche den Fokus hat zB Stans Antwort) In meinem Fall wollte ich zulassen, dass enter das Formular absendet, auch wenn der aktuelle Fokus des Benutzers auf dem Textfeld lag.

Ich habe auch ein 'name'-Attribut anstelle von' id 'verwendet, aber dies ist der gleiche Ansatz.

var pressedButtonName =
     typeof $(":input[type=submit]:focus")[0] === "undefined" ?
     $(":input[type=submit]:first")[0].name :
     $(":input[type=submit]:focus")[0].name;
6
andrewmo

Wenn Sie mit dem Hinzufügen eines .click-Ereignisses nicht meinen, dass Sie keine separaten Handler für diese Ereignisse haben möchten, können Sie alle Klicks (Senden) in einer Funktion behandeln:

$(document).ready(function(){
  $('input[type="submit"]').click( function(event){ process_form_submission(event); } );
});

function process_form_submission( event ) {
  event.preventDefault();
  //var target = $(event.target);
  var input = $(event.currentTarget);
  var which_button = event.currentTarget.value;
  var data = input.parents("form")[0].data.value;
//  var which_button = '?';       // <-- this is what I want to know
  alert( 'data: ' + data + ', button: ' + which_button );
}
4
jcane86

Dieser hat für mich gearbeitet

$('#Form').submit(function(){
var btn= $(this).find("input[type=submit]:focus").val();
alert('you have clicked '+ btn);

}
4
Saheb Mondal

Für mich waren die besten Lösungen folgende:

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

   // Get the button that was clicked       
   var submit = $(this.id).context.activeElement;

   // You can get its name like this
   alert(submit.name)

   // You can get its attributes like this too
   alert($(submit).attr('class'))

});
3

Wenn Sie mit dieser exzellenten Antwort arbeiten, können Sie das aktive Element (die Schaltfläche) überprüfen, eine ausgeblendete Eingabe an das Formular anhängen und optional am Ende des Übergabehandlers entfernen.

$('form.form-js').submit(function(event){
    var frm = $(this);
    var btn = $(document.activeElement);
    if(
        btn.length &&
        frm.has(btn) &&
        btn.is('button[type="submit"], input[type="submit"], input[type="image"]') &&
        btn.is('[name]')
    ){
        frm.append('<input type="hidden" id="form-js-temp" name="' + btn.attr('name') + '" value="' + btn.val() + '">');
    }

    // Handle the form submit here

    $('#form-js-temp').remove();
});

Randbemerkung: Ich füge persönlich die Klasse form-js in allen Formularen hinzu, die über JavaScript übermittelt werden. 

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

verborgenes Feld hinzufügen

3
anydasa

Da ich die akzeptierte Antwort nicht kommentieren kann, bringe ich hier eine modifizierte Version mit, die Elemente berücksichtigen sollte, die sich außerhalb des Formulars befinden (dh: mit dem Attribut form an das Formular angehängt). Dies ist für moderne Browser: http://caniuse.com/#feat=form-attribute . Das closest('form') wird als Fallback für das nicht unterstützte form-Attribut verwendet

$(document).on('click', '[type=submit]', function() {
    var form = $(this).prop('form') || $(this).closest('form')[0];
    $(form.elements).filter('[type=submit]').removeAttr('clicked')
    $(this).attr('clicked', true);
});

$('form').on('submit', function() {
    var submitter = $(this.elements).filter('[clicked]');
})
2
user3074069

Dies ist die von mir verwendete Lösung und funktioniert sehr gut:

// prevent enter key on some elements to prevent to submit the form
function stopRKey(evt) {
  evt = (evt) ? evt : ((event) ? event : null);
  var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
  var alloved_enter_on_type = ['textarea'];
  if ((evt.keyCode == 13) && ((node.id == "") || ($.inArray(node.type, alloved_enter_on_type) < 0))) {
    return false;
  }
}

$(document).ready(function() {
  document.onkeypress = stopRKey;
  // catch the id of submit button and store-it to the form
  $("form").each(function() {
    var that = $(this);

    // define context and reference
    /* for each of the submit-inputs - in each of the forms on
			 the page - assign click and keypress event */
    $("input:submit,button", that).bind("click keypress", function(e) {
      // store the id of the submit-input on it's enclosing form
      that.data("callerid", this.id);
    });
  });

  $("#form1").submit(function(e) {
    var Origin_id = $(e.target).data("callerid");
    alert(Origin_id);
    e.preventDefault();

  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form id="form1" name="form1" action="" method="post">
  <input type="text" name="text1" />
  <input type="submit" id="button1" value="Submit1" name="button1" />
  <button type="submit" id="button2" name="button2">
    Submit2
  </button>
  <input type="submit" id="button3" value="Submit3" name="button3" />
</form>

2
vasilenicusor

Ähnlich wie Stan Antwort aber: 

  • wenn Sie mehr als eine Taste haben, müssen Sie nur die erste Taste => [0] erhalten. 
  • wenn das Formular mit der Eingabetaste gesendet werden kann, müssen Sie eine Standardeinstellung => myDefaultButtonId verwalten

$(document).on('submit', function(event) {
    event.preventDefault();
    var pressedButtonId = 
         typeof $(":input[type=submit]:focus")[0] === "undefined" ? 
         "myDefaultButtonId" :
         $(":input[type=submit]:focus")[0].id;
    ...
 }
2
yann-h

Es hat mir geholfen https://stackoverflow.com/a/17805011/1029257

Das Formular wurde erst gesendet, nachdem auf die Schaltfläche "Senden" geklickt wurde.

var theBtn = $(':focus');
if(theBtn.is(':submit'))
{
  // ....
  return true;
}

return false;
1
w4kskl

Um zu unterscheiden, welche <Taste> oder <Eingabetyp = "Taste" ...> gedrückt wird, können Sie deren 'id' überprüfen:

$("button").click(function() {
  var id = $(this).attr('id');
  ... 
});
0
Apostolos

Hier ist ein Beispiel, das this.form verwendet, um die korrekte Form des Submit zu erhalten, und Datenfelder zum Speichern des zuletzt angeklickten/fokussierten Elements. Ich habe auch Absendungscode in ein Timeout eingebunden, um sicherzustellen, dass Klickereignisse vor der Ausführung ausgeführt werden (einige Benutzer berichteten in Kommentaren, dass in Chrome manchmal ein Klickereignis nach einem Absenden ausgelöst wird).

Funktioniert beim Navigieren sowohl mit Tasten als auch mit Maus/Fingern, ohne auf Browser zu zählen, um ein Klickereignis mit der RETURN-Taste zu senden (obwohl es nicht weh tut). Ich habe einen Ereignishandler für Fokusereignisse für Schaltflächen und Felder hinzugefügt.

Sie können den Elementen, die sich beim Klicken selbst speichern, Schaltflächen des Typs "Senden" hinzufügen.

In der Demo habe ich einen roten Rahmen gesetzt, um das ausgewählte Element anzuzeigen, und eine Warnung, die Name und Wert/Bezeichnung anzeigt.

Hier ist die GEIGE

Und hier ist der (gleiche) Code:

Javascript:

$("form").submit(function(e) {
  e.preventDefault();
  // Use this for rare/buggy cases when click event is sent after submit
  setTimeout(function() {

    var $this=$(this);
    var lastFocus = $this.data("lastFocus");
    var $defaultSubmit=null;

    if(lastFocus) $defaultSubmit=$(lastFocus);

    if(!$defaultSubmit || !$defaultSubmit.is("input[type=submit]")) {
      // If for some reason we don't have a submit, find one (the first)
      $defaultSubmit=$(this).find("input[type=submit]").first();
    }

    if($defaultSubmit) {
      var submitName=$defaultSubmit.attr("name");
      var submitLabel=$defaultSubmit.val();

       // Just a demo, set hilite and alert
      doSomethingWith($defaultSubmit);
      setTimeout(function() {alert("Submitted "+submitName+": '"+submitLabel+"'")},1000);
    } else {
      // There were no submit in the form
    }

  }.bind(this),0);

});

$("form input").focus(function() {
  $(this.form).data("lastFocus", this);
});
$("form input").click(function() {
  $(this.form).data("lastFocus", this);
});

// Just a demo, setting hilite
function doSomethingWith($aSelectedEl) {
  $aSelectedEl.css({"border":"4px solid red"});
  setTimeout(function() { $aSelectedEl.removeAttr("style"); },1000);
}

DUMMY HTML:

<form>
<input type="text" name="testtextortexttest" value="Whatever you write, sir."/>
<input type="text" name="moretesttextormoretexttest" value="Whatever you write, again, sir."/>

<input type="submit" name="test1" value="Action 1"/>
<input type="submit" name="test2" value="Action 2"/>
<input type="submit" name="test3" value="Action 3"/>
<input type="submit" name="test4" value="Action 4"/>
<input type="submit" name="test5" value="Action 5"/>
</form>

DUMB CSS:

input {display:block}
0
FrancescoMM

Sie können den Eingabetyp = "ausgeblendet" als Halter für eine Tasten-ID-Information erstellen.

<input type="hidden" name="button" id="button">
<input type="submit" onClick="document.form_name.button.value = 1;" value="Do something" name="do_something">

In diesem Fall übergibt das Formular beim Senden den Wert "1" (ID Ihrer Schaltfläche). Dies funktioniert, wenn onClick vor dem Senden (?) Erfolgt.

0
darekk

Ich schreibe diese Funktion, die mir hilft

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

und dann Verwenden

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

Ich habe auch eine Lösung gemacht, und das funktioniert ganz gut: 
Es verwendet jQuery und CSS


Zuerst habe ich eine schnelle CSS-Klasse erstellt, diese kann eingebettet sein oder in einer separaten Datei.

<style type='text/css'>
    .Clicked {
        /*No Attributes*/
    }
</style>


Fügen Sie anschließend beim Klickereignis einer Schaltfläche im Formular die CSS-Klasse zur Schaltfläche hinzu. Wenn die Schaltfläche bereits über die CSS-Klasse verfügt, entfernen Sie sie. (Wir wollen nicht zwei CSS-Klassen [Nur für den Fall]).

    // Adds a CSS Class to the Button That Has Been Clicked.
    $("form :input[type='submit']").click(function () 
    {
        if ($(this).hasClass("Clicked"))
        {
            $(this).removeClass("Clicked");
        }
        $(this).addClass("Clicked");
    });


Testen Sie nun die Schaltfläche, um zu sehen, dass sie über die CSS-Klasse verfügt. Wenn die getestete Schaltfläche nicht über CSS verfügt, wird die andere Schaltfläche angezeigt.

    // On Form Submit
    $("form").submit(function ()
    {
        // Test Which Button Has the Class
        if ($("input[name='name1']").hasClass("Clicked"))
        {
            // Button 'name1' has been clicked.
        }
        else
        {
           // Button 'name2' has been clicked.
        }
    });

Ich hoffe, das hilft!.

0
Jason Cidras