84

I have several buttons on my page, but I'm not sure how to tell which one was clicked. Here's the markup for my two buttons:

<input type="submit" id="btnSubmit" value="Save Changes" />
<input type="submit" id="btnDelete" value="Delete" />
wonea
  • 4,783
  • 17
  • 86
  • 139
Sonny Boy
  • 7,848
  • 18
  • 76
  • 104
  • Related: *[How can PHP determine if the user pressed the Enter key or Submit button?](https://stackoverflow.com/questions/795132)* – Peter Mortensen Jul 14 '19 at 19:10
  • 1
    This answer seem to have a big error. It should use name ="btnSubmit" not id="btnSubmit" and name ="btnDelete" not id="btnDelete". All those people that upvoted this did they really test it? – webzy Jun 16 '21 at 00:11

4 Answers4

158

With an HTML form like:

<input type="submit" name="btnSubmit" value="Save Changes">
<input type="submit" name="btnDelete" value="Delete">

(using <form method=POST)

The PHP code to use would look like:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  // Something posted

  if (isset($_POST['btnDelete'])) {
    // btnDelete 
  } else {
    // Assume btnSubmit 
  }
}

You should always assume or default to the first submit button to appear in the form HTML source code. In practice, the various browsers reliably send the name/value of a submit button with the post data when:

  1. The user literally clicks the submit button with the mouse or pointing device
  2. Or there is focus on the submit button (they tabbed to it), and then the Enter key is pressed.

Other ways to submit a form exist, and some browsers/versions decide not to send the name/value of any submit buttons in some of these situations. For example, many users submit forms by pressing the Enter key when the cursor/focus is on a text field. Forms can also be submitted via JavaScript, as well as some more obscure methods.

It's important to pay attention to this detail, otherwise you can really frustrate your users when they submit a form, yet "nothing happens" and their data is lost, because your code failed to detect a form submission, because you did not anticipate the fact that the name/value of a submit button may not be sent with the post data.

Also, the above advice should be used for forms with a single submit button too because you should always assume a default submit button.

I'm aware that the Internet is filled with tons of form-handler tutorials, and almost of all them do nothing more than check for the name and value of a submit button. But, they're just plain wrong!

Edit, here's more examples:

3+ button form:

<input type="submit" name="btnSubmit1" value="1">
<input type="submit" name="btnSubmit2" value="2">
<input type="submit" name="btnSubmit3" value="3">

php:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  // Something posted

  if (isset($_POST['btnSubmit3'])) {
    // btnSubmit3 
  } else if (isset($_POST['btnSubmit2'])) {
    // btnSubmit2 
  } else {
    // Assume btnSubmit1 
  }
}

Single button form:

<input type="submit" name="btnSubmit1" value="1">

php:

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  // Something posted

  // Assume btnSubmit1 
}

Notice that in all cases, you can and should assume the first submit button to appear in the form's html was the button that was clicked, unless you can detect a different button. Only the buttons which appear later in the form should be explicitly tested for.

In other words, the first button is always assumed to be the form submitter, unless you can detect a different button as the submitter.

What about <form method="GET" ?
The reason we can use $_SERVER['REQUEST_METHOD'] === 'POST' to detect a form POST is because POST is deliberate, while GET is not - GET is the default. So, using $_SERVER['REQUEST_METHOD'] === 'GET' would be unreliable, because someone may just be loading the page/url, and not actually submitting a form, as the browser will use GET in either scenario because it is the default request method.

There's a variety of different ways to reliably detect a GET form submission, but a simple and reliable method is to just add <input type=hidden name=submitted value=1> to the form, and then instead of using if ($_SERVER['REQUEST_METHOD'] === 'POST') do if (isset($_GET['submitted'])) to detect form submission. The code detecting which button was pressed stays the same as it was for POST.

Browser Support:
This strategy has excellent browser support and does not rely on any browser specific behavior, nor any newer html5 features. It should work properly with both modern and ancient browsers, even from the early 2000's. Also, the php code logic is easily adapted to other languages because it does not rely on any tricky or php-specific behaviors.

goat
  • 31,486
  • 7
  • 73
  • 96
  • 1
    Thanks for the extra info about assuming a default button... easy to overlook. – kad81 May 18 '13 at 02:59
  • why does this use else instead of else if? – GeorgeButter Sep 08 '16 at 12:27
  • @Gorg else if what? What would you test for, and why? – goat Sep 08 '16 at 23:56
  • @goat Would it be more secure to specify that btnSubmit has definitely been clicked? Could the user change the value of the button and submit different data? – GeorgeButter Sep 09 '16 at 00:08
  • 2
    @Gorg if you're talking about a user who's trying to trick you, there's nothing you can do to stop that. This is a reality you must accept with client / server programming - the client can *easily* send you *any* data it wants. It's common to user server-side storage, (eg server-side sessions) to store data that you don't want the user to be able to tamper with. – goat Sep 27 '16 at 02:14
  • You can use GET too, but the method of detecting form submission will need to change to looking for a non-optional form field in the `$_GET` data. Eg, use an `` and then check via `if (isset($_GET['submit'])) { ...` instead of testing the `REQUEST_METHOD`. – goat May 06 '18 at 23:45
  • I think what @Buts was trying to get at is that if the form has more than two buttons, you'll want to use an if/elseif/else that checks each button in the form before arriving at the default. – Lee Blake Jul 18 '19 at 07:09
  • 1
    For the reason of practicality (to avoid the edit hanging or, worse, rejected), I went ahead and approved the edit fixing a supposed typo you might've made when changing `name` attributes to `id`s in your latest edit, as well as some minor highlighting updates by explicitly specifying language hints and code blocks. Feel free to roll back if you think the edit is incorrect, but switching to `id` would definitely made the input not being sent when the form is submitted. – Oleg Valter is with Ukraine Nov 09 '21 at 01:12
14

In HTML:

<input type="submit" id="btnSubmit" name="btnSubmit" value="Save Changes" />
<input type="submit" id="btnDelete" name="btnDelete" value="Delete" />

In PHP:

if (isset($_POST["btnSubmit"])){
  // "Save Changes" clicked
} else if (isset($_POST["btnDelete"])){
  // "Delete" clicked
}
MiffTheFox
  • 21,302
  • 14
  • 69
  • 94
  • 5
    Sorry, gotta downvote. Forms handlers that misbehave when using the enter key to submit are a pet peeve of mine. – goat Apr 21 '10 at 04:15
  • 5
    @chris - That's okay, you make a perfectly valid point. Upvoted your answer. – MiffTheFox Apr 21 '10 at 07:09
1

All you need to give the name attribute to the each button. And you need to address each button press from the PHP script. But be careful to give each button a unique name. Because the PHP script only take care of the name most of the time

<input type="submit" name="Submit_this" id="This" />
-3

Are you asking in php or javascript.

If it is in php, give the name of that and use the post or get method, after that you can use the option of isset or that particular button name is checked to that value.

If it is in js, use getElementById for that

Karthik
  • 3,221
  • 5
  • 28
  • 38