0

I have a form I'm submitting with javascript (with react specifically, but I don't think it matters for the purposes of the question).

The form has a few inputs and two buttons. One is a normal submit button, and one triggers a secondary action.

Crucially, the secondary button comes first in the HTML order and I can't change this (not even with flexbox order).

Frustratingly, this seems to mean that when the user finishes typing and hits enter, the secondary button gets triggered.

I'm listening to the form's submit event for the primary action, which is what I would have thought hitting enter would trigger. The secondary button has a click event listener on it.

How can I make it so the form's primary action gets triggered on pressing enter?

The secondary action should only happen if the user clicks that button or explicitly focuses onto it and hits enter.

You can think of the form as structured like this:

<form onSubmit={primaryAction}>

   <input ... />
   <input ... />

   <button onClick={secondaryAction}>Second action</>

   <button>Submit</button>
</form>

I've also tried:

  • Reorganising the HTML so that the primary button comes first in the HTML order. Some sources say this works but it's not an option because I'm using absolute positioning on this form and futzing with the HTML order (even with flexbox order) breaks the layout.
  • Using the submitter property on the form's submit event. This doesn't seem to work cross-browser yet.

A good example of what I'm trying to achieve is Deliveroo's home page. On the version I see there's a form with one text input and two actions (use my current location and search). When you hit enter, it's the primary (search) action that gets triggered despite the button for the secondary coming first in the html order.

parasomnist
  • 178
  • 1
  • 12

2 Answers2

1

This should solve the problem, or at least give you some ideas how to solve it. It is hard to write solution without seeing rest of your code.

First button will be type of button, second will be submit.

<form onSubmit={primaryAction}>
  <input type="text" />
  <button type="button" onClick={secondaryAction}>
    Second action
  </button>
  <button type="submit">Submit</button>
</form>
0

To do this in a way where it will work cross browser will require a bit of a hack if you cannot change the HTML order (but you can modify the HTML).

The below solution works without JavaScript as well.

What we do is add a button that is both hidden and inaccessible via keyboard. This button comes first in the DOM order so will be the default action in browsers (most browsers....IE may play up and haven't tested in Opera)

To produce this button we use the hidden-button class to make the button invisible. We also add tabindex="-1" so that it cannot be accessed via keyboard.

This button would have the same action as your primary action.

In the below example I have added console logs so you can confirm it works

function hiddenBtn(){
    console.log("hidden button");
    return false;
}
function wrongBtn(){
    console.log("'wrong' button");
    return false;
}
function submitBtn(){
    console.log("submit button");
    return false;
}
.hidden-button{
    position: absolute !important;
    height: 1px; 
    width: 1px;
    overflow: hidden;
    clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
    clip: rect(1px, 1px, 1px, 1px);
    white-space: nowrap; /* added line */
}
<form>
    <input/>
   <input/>

  <button class="hidden-button" onclick="return hiddenBtn()" tabindex="-1">Submit</button>

   <button onClick="return wrongBtn()">Second action</button>

   <button onclick="return submitBtn()">Submit</button>
</form>
GrahamTheDev
  • 22,724
  • 2
  • 32
  • 64