ChatGPT解决这个技术问题 Extra ChatGPT

Multiple submit buttons in an HTML form

Let's say you create a wizard in an HTML form. One button goes back, and one goes forward. Since the back button appears first in the markup when you press Enter, it will use that button to submit the form.

Example:

I would like to get to decide which button is used to submit the form when a user presses Enter. That way, when you press Enter the wizard will move to the next page, not the previous. Do you have to use tabindex to do this?

Just use for float: left

P
Peter Mortensen

I'm just doing the trick of floating the buttons to the right.

This way the Prev button is left of the Next button, but the Next comes first in the HTML structure:

.f { float: right; } .clr { clear: both; }

Benefits over other suggestions: no JavaScript code, accessible, and both buttons remain type="submit".


Please don't do this without also changing the tab order, so that hitting the tab button will cycle through the buttons as they appear on screen.
Sadly this only works if the buttons are relatively close to each other. In more complicated situations, like a bigger page with several buttons spread over each corner but all in one single form this is simply unmanageable.
P
Peter Mortensen

Change the previous button type into a button like this:

<input type="button" name="prev" value="Previous Page" />

Now the Next button would be the default, plus you could also add the default attribute to it so that your browser will highlight it like so:

<input type="submit" name="next" value="Next Page" default />

What default attribute are you talking about? There is no "default" attribute, which would be valid: w3.org/html/wg/drafts/html/master/… (not in HTML5, HTML 4.01 Transitional/Strict, XHTML 1.0 Strict). And I don't see why changing the input type from submit to button would be better. You can have multiple submit type input elements in one form without a problem. I don't really understand why this answer is so upvoted.
Having an input of type "button" doesn't execute the form action. You can have an onclick or something, thus executing another function than the "default" form action (which is executed by pressing the "submit"-type button). That's what I was looking for and that's why I upvoted it. Can't speak for the "default" attribute, wasn't part of my problem;) thanks for your clarification, though.
@Sk8erPeter, @Jonas .... hmm.. I suspect this default attribute is a Global attribute; enumerated attribute.. which is related to enumeration states: w3.org/html/wg/drafts/html/master/… . apart from that point.. the button aspect of the this answer is not an answer.. it's a 'conditional suggestion' or a query (question itself).
@Jonas: yes, type="button" doesn't submit the form, type="submit" does, but changing the type of these buttons is definitely not a solution, because these buttons should basically behave the same way - the OP's question was how to make the "Next" button the default for pressing the Enter key. And there's a possible solution in the accepted answer.
@BrettCaswell: changing the type of these buttons is a bad workaround (see my previous comment). There is no valid default attribute for input tags (as I stated earlier) in HTML, and the (popular) browsers will NOT highlight the button which has this attribute, which means there is no nonstandard implementation of this attribute - so I still don't know what @Wally Lawless was talking about, and why this answer is so overrated. There is only one valid default attribute introduced in HTML5, BUT only for the <track> tag: developer.mozilla.org/en-US/docs/Web/HTML/Element/track
P
Peter Mortensen

Give your submit buttons the same name like this:

<input type="submit" name="submitButton" value="Previous Page" />
<input type="submit" name="submitButton" value="Next Page" />

When the user presses Enter and the request goes to the server, you can check the value for submitButton on your server-side code which contains a collection of form name/value pairs. For example, in ASP Classic:

If Request.Form("submitButton") = "Previous Page" Then
    ' Code for the previous page
ElseIf Request.Form("submitButton") = "Next Page" Then
    ' Code for the next page
End If

Reference: Using multiple submit buttons on a single form


This is not what the user asked. The user wanted to know how to control which submit button in a form is activated when enter is pressed ie. which is the default button.
doesn't work in an I18n application where you even dont know the label of the button.
In what system or technology solution would the server itself not know what the label that was used for the next and back button? Did not the server generate the next and back button in the first place? (If the localisation is handled on the client side, I imagine the server may not know, but I have never heard of this for HTML)
This answer completely misses the question, likely it is for a different question. Why so many upvotes??? Not to mention that one should never check for the label of the button... calls for a lot of trouble. Even the simple case: "we should abbreviate the string to 'Prev. Page' " will ruin your sites functionality.
P
Peter Mortensen

If the fact that the first button is used by default is consistent across browsers, put them the right way around in the source code, and then use CSS to switch their apparent positions.

float them left and right to switch them around visually, for example.


A
AliNajafZadeh

Sometimes the provided solution by palotasb is not sufficient. There are use cases where for example a "Filter" submits button is placed above buttons like "Next and Previous". I found a workaround for this: copy the submit button which needs to act as the default submit button in a hidden div and place it inside the form above any other submit button.

Technically it will be submitted by a different button when pressing Enter than when clicking on the visible Next button. But since the name and value are the same, there's no difference in the result.

Filtered results

Filtered result 1 Filtered result 2 Filtered result 3


P
Peter Mortensen

This cannot be done with pure HTML. You must rely on JavaScript for this trick.

However, if you place two forms on the HTML page you can do this.

Form1 would have the previous button.

Form2 would have any user inputs + the next button.

When the user presses Enter in Form2, the Next submit button would fire.


P
Peter Mortensen

I would use JavaScript to submit the form. The function would be triggered by the OnKeyPress event of the form element and would detect whether the Enter key was selected. If this is the case, it will submit the form.

Here are two pages that give techniques on how to do this: 1, 2. Based on these, here is an example of usage (based on here):

<SCRIPT TYPE="text/javascript">//<!--
function submitenter(myfield,e) {
  var keycode;
  if (window.event) {
    keycode = window.event.keyCode;
  } else if (e) {
    keycode = e.which;
  } else {
    return true;
  }

  if (keycode == 13) {
    myfield.form.submit();
    return false;
  } else {
    return true;
  }
}
//--></SCRIPT>

<INPUT NAME="MyText" TYPE="Text" onKeyPress="return submitenter(this,event)" />

What happens if javascript is disabled?
You shouldn't use to comment out JS, these tags are not Javascript language tokens
@Marecky They're not to comment out JS. They are ignored when parsing the contents of


K
Kenny Johnson

Changing the tab order should be all it takes to accomplish this. Keep it simple.

Another simple option would be to put the back button after the submit button in the HTML code but float it to the left so it appears on the page before the submit button.


The tab order is ignored when deciding which button to be the default one. According to HTML spec: A form element's default button is the first submit button in tree order whose form owner is that form element.
P
Peter Mortensen

Another simple option would be to put the back button after the submit button in the HTML code, but float it to the left, so it appears on the page before the submit button.

Changing the tab order should be all it takes to accomplish this. Keep it simple.


P
Peter Mortensen

The first time I came up against this, I came up with an onclick()/JavaScript hack when choices are not prev/next that I still like for its simplicity. It goes like this:

@model myApp.Models.myModel

<script type="text/javascript">
    function doOperation(op) {
        document.getElementById("OperationId").innerText = op;
        // you could also use Ajax to reference the element.
    }
</script>

<form>
  <input type="text" id = "TextFieldId" name="TextField" value="" />
  <input type="hidden" id="OperationId" name="Operation" value="" />
  <input type="submit" name="write" value="Write" onclick='doOperation("Write")'/>
  <input type="submit" name="read" value="Read" onclick='doOperation("Read")'/>
</form>

When either submit button is clicked, it stores the desired operation in a hidden field (which is a string field included in the model the form is associated with) and submits the form to the Controller, which does all the deciding. In the Controller, you simply write:

// Do operation according to which submit button was clicked
// based on the contents of the hidden Operation field.
if (myModel.Operation == "Read")
{
     // Do read logic
}
else if (myModel.Operation == "Write")
{
     // Do write logic
}
else
{
     // Do error logic
}

You can also tighten this up slightly using numeric operation codes to avoid the string parsing, but unless you play with enumerations, the code is less readable, modifiable, and self-documenting and the parsing is trivial, anyway.


If you read the question carefully, there is no mention about 'clicking' a submit button, it is all about pressing Enter in a textfield and defining which button gets activated. The code you provide is for a different problem, which already has several good solutions, albeit yours is a nice one as well. Do you have a solution for the original question?
n
nikkypx

From https://html.spec.whatwg.org/multipage/forms.html#implicit-submission

A form element's default button is the first submit button in tree order whose form owner is that form element. If the user agent supports letting the user submit a form implicitly (for example, on some platforms hitting the "enter" key while a text field is focused implicitly submits the form)...

Having the next input be type="submit" and changing the previous input to type="button" should give the desired default behavior.

<form>
   <input type="text" name="field1" /> <!-- put your cursor in this field and press Enter -->

   <input type="button" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
   <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

P
Peter Mortensen

This is what I have tried out:

You need to make sure you give your buttons different names Write an if statement that will do the required action if either button is clicked.

<form>
    <input type="text" name="field1" /> <!-- Put your cursor in this field and press Enter -->

    <input type="submit" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
    <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

In PHP,

if(isset($_POST['prev']))
{
    header("Location: previous.html");
    die();
}

if(isset($_POST['next']))
{
    header("Location: next.html");
    die();
}

The problem is that hitting enter on a text field will submit the form with the first submit button, not with the intended one (second one in the example). Finding out which submit button was used to submit the form is easy, and that was not the question!
P
Peter Mortensen

I came across this question when trying to find an answer to basically the same thing, only with ASP.NET controls, when I figured out that the ASP button has a property called UseSubmitBehavior that allows you to set which one does the submitting.

<asp:Button runat="server" ID="SumbitButton" UseSubmitBehavior="False" Text="Submit" />

Just in case someone is looking for the ASP.NET button way to do it.


T
Tylla
<input type="submit" name="prev" value="Previous Page"> 
<input type="submit" name="prev" value="Next Page"> 

Keep the name of all submit buttons the same: "prev".

The only difference is the value attribute with unique values. When we create the script, these unique values will help us to figure out which of the submit buttons was pressed.

And write the following coding:

    btnID = ""
if Request.Form("prev") = "Previous Page" then
    btnID = "1"
else if Request.Form("prev") = "Next Page" then
    btnID = "2"
end if

The problem is that hitting enter on a text field will submit the form with the first submit button, not with the intended one (second one in the example). Finding out which submit button was used to submit the form is easy, and that was not the question!
P
Peter Mortensen

With JavaScript (here jQuery), you can disable the prev button before submitting the form.

$('form').on('keypress', function(event) {
    if (event.which == 13) {
        $('input[name="prev"]').prop('type', 'button');
    }
});

P
Peter Mortensen

I solved a very similar problem in this way:

If JavaScript is enabled (in most cases nowadays) then all the submit buttons are "degraded" to buttons at page load via JavaScript (jQuery). Click events on the "degraded" button typed buttons are also handled via JavaScript. If JavaScript is not enabled then the form is served to the browser with multiple submit buttons. In this case hitting Enter on a textfield within the form will submit the form with the first button instead of the intended default, but at least the form is still usable: you can submit with both the prev and next buttons.

Working example:

If JavaScript is disabled, then you CAN submit the form with button1, button2 or button3. If you press enter on a text field, then the form is submitted with the first submit button. If JavaScript is enabled, then the submit typed buttons without the 'defaultSubmitButton' style are converted to button typed buttons. If you press Enter on a text field, then the form is submitted with the only submit button (the one with class defaultSubmitButton) If you click on any other button in the form, then the form is submitted with that button's value.



P
Peter Mortensen

You can use Tabindex to solve this issue. Also changing the order of the buttons would be a more efficient way to achieve this.

Change the order of the buttons and add float values to assign them the desired position you want to show in your HTML view.


S
Stoppeye

A maybe somewhat more modern approach over the CSS float method could be a solution using flexbox with the order property on the flex items. It could be something along those lines:

<div style="display: flex">
  <input type="submit" name="next" value="Next Page" style="order: 1" />
  <input type="submit" name="prev" value="Previous Page" style="order: 0" />
</div>

Of course it depends on your document structure whether this is a feasible approach or not, but I find flex items much easier to control than floating elements.


佚名

Instead of struggling with multiple submits, JavaScript or anything like that to do some previous/next stuff, an alternative would be to use a carousel to simulate the different pages. Doing this :

You don't need multiple buttons, inputs or submits to do the previous/next thing, you have only one input type="submit" in only one form.

The values in the whole form are there until the form is submitted.

The user can go to any previous page and any next page flawlessly to modify the values.

Example using Bootstrap 5.0.0 :

<div id="carousel" class="carousel slide" data-ride="carousel">
    <form action="index.php" method="post" class="carousel-inner">
        <div class="carousel-item active">
            <input type="text" name="lastname" placeholder="Lastname"/>
        </div>
        <div class="carousel-item">
            <input type="text" name="firstname" placeholder="Firstname"/>
        </div>
        <div class="carousel-item">
            <input type="submit" name="submit" value="Submit"/>
        </div>
    </form>
    <a class="btn-secondary" href="#carousel" role="button" data-slide="prev">Previous page</a>
    <a class="btn-primary" href="#carousel" role="button" data-slide="next">Next page</a>
</div>

P
Peter Mortensen

I think this is an easy solution for this. Change the Previous button type to button, and add a new onclick attribute to the button with value jQuery(this).attr('type','submit');.

So, when the user clicks on the Previous button then its type will be changed to submit and the form will be submitted with the Previous button.

<form>
  <!-- Put your cursor in this field and press Enter -->
  <input type="text" name="field1" />

  <!-- This is the button that will submit -->
  <input type="button" onclick="jQuery(this).attr('type','submit');" name="prev" value="Previous Page" />

  <!-- But this is the button that I WANT to submit -->
  <input type="submit" name="next" value="Next Page" />
</form>

M
Motine

Problem

A form may have several submit buttons. When pressing return in any input, the first submit button is used by the browser. However, sometimes we want to use a different/later button as default.

Options

Add a hidden submit button with the same action first (☹️ duplication) Put the desired submit button first in the form and then move it to the correct place via CSS (☹️ may not be feasible, may result in cumbersome styling) Change the handling of the return key in all form inputs via JavaScript (☹️ needs javascript)

None of the options is ideal, so we choose 3. because most browsers have JavaScript enabled.

Chosen solution

// example implementation document.addEventListener('DOMContentLoaded', (ev) => { for (const defaultSubmitInput of document.querySelectorAll('[data-default-submit]')) { for (const formInput of defaultSubmitInput.form.querySelectorAll('input')) { if (formInput.dataset.ignoreDefaultSubmit != undefined) { continue; } formInput.addEventListener('keypress', (ev) => { if (ev.keyCode == 13) { ev.preventDefault(); defaultSubmitInput.click(); } }) } } });

It may be useful to be able to remove the enhancement from some inputs. This can be achieved by:

<input type="text" name="field2" data-ignore-default-submit> <!-- uses browser standard behaviour -->

Here a complete code pen.


P
Peter Mortensen

When a button is clicked with a mouse (and hopefully by touch), it records the X,Y coordinates. This is not the case when it is invoked by a form, and these values are normally zero.

So you can do something like this:

function(e) {
  const isArtificial = e.screenX === 0 && e.screenY === 0
    && e.x === 0 && e.y === 0
    && e.clientX === 0 && e.clientY === 0;

    if (isArtificial) {
      return; // DO NOTHING
    } else {
      // OPTIONAL: Don't submit the form when clicked
      // e.preventDefault();
      // e.stopPropagation();
    }

    // ...Natural code goes here
}

You seem to have confused multiple button inputs with a single image input.
Not really, e is expected to be a MouseEvent. Have a look at the properties (developer.mozilla.org/en-US/docs/Web/API/MouseEvent).
If the button was clicked with a Mouse, isArtificial will be false. Because, properties like clientX or clientY will not be zero, but the mouse coordinates.
What is "natural code"?
Yes, in retrospect I could have worded this answer more clearly. Natural code in this case refers to code that is meant for instances where the form did not automatically invoke the event handler. Instances where the user actively clicked (or tapped) the submit button.
P
Peter Mortensen

Using the example you gave:

<form>
    <input type="text" name="field1" /><!-- Put your cursor in this field and press Enter -->
    <input type="submit" name="prev" value="Previous Page" /> <!-- This is the button that will submit -->
    <input type="submit" name="next" value="Next Page" /> <!-- But this is the button that I WANT to submit -->
</form>

If you click on "Previous Page", only the value of "prev" will be submitted. If you click on "Next Page" only the value of "next" will be submitted.

If however, you press Enter somewhere on the form, neither "prev" nor "next" will be submitted.

So using pseudocode you could do the following:

If "prev" submitted then
    Previous Page was click
Else If "next" submitted then
    Next Page was click
Else
    No button was click

There's never a situation (without using js) when none of the buttons is triggered. If you hit ENTER the first button in the code will catch the event. In the html-example it is the prev-button.