Question

How to Prevent Buttons from Submitting Forms in HTML and JavaScript

htmljavascript

Question

In the following HTML page, Firefox submits the form when the Remove Last Item button is clicked, while the Add Item button does not appear to behave the same way.

How can I prevent the Remove Last Item button from submitting the form?

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<html>
<body>
  <form autocomplete="off" method="post" action="">
    <p>Title:<input type="text" /></p>

    <button onclick="addItem(); return false;">Add Item</button>
    <button onclick="removeItem(); return false;">Remove Last Item</button>

    <table>
      <th>Name</th>
      <tr>
        <td><input type="text" id="input1" name="input1" /></td>
        <td><input type="hidden" id="input2" name="input2" /></td>
      </tr>
    </table>

    <input id="submit" type="submit" name="submit" value="Submit" />
  </form>
</body>
</html>
function addItem() {
  var v = $('form :hidden:last').attr('name');
  var n = /(.*)input/.exec(v);

  var newPrefix;
  if (n[1].length == 0) {
    newPrefix = '1';
  } else {
    newPrefix = parseInt(n[1]) + 1;
  }

  var oldElem = $('form tr:last');
  var newElem = oldElem.clone(true);
  var lastHidden = $('form :hidden:last');

  lastHidden.val(newPrefix);

  var pat = '=\"' + n[1] + 'input';

  newElem.html(newElem.html().replace(new RegExp(pat, 'g'), '=\"' + newPrefix + 'input'));
  newElem.appendTo('table');
  $('form :hidden:last').val('');
}

function removeItem() {
  var rows = $('form tr');
  if (rows.length > 2) {
    rows[rows.length - 1].html('');
    $('form :hidden:last').val('');
  } else {
    alert('Cannot remove any more rows');
  }
}

Short Answer

By the end of this page, you will understand why some buttons inside a form submit the form automatically, how the browser decides button behavior, and how to stop that submission safely using type="button", event handling, or form submit prevention in JavaScript.

Concept

In HTML, a <button> placed inside a <form> is treated as a submit button by default unless you explicitly say otherwise.

That means this button:

<button>Remove Last Item</button>

is effectively treated like this:

<button type="submit">Remove Last Item</button>

When clicked, the browser tries to submit the form.

This matters because many forms contain buttons that are not meant to submit anything. For example:

  • add a row
  • remove a row
  • preview data
  • open a dialog
  • validate fields first

If you do not explicitly set the button type, the browser may submit the form when the button is clicked. Different browsers may appear to behave slightly differently depending on inline handlers, DOM changes, or timing, but the core rule is the same: inside a form, <button> defaults to submit.

The most reliable fix is to use:

<button type="button">Remove Last Item</button>

This tells the browser: “this is a normal clickable button, not a submit button.”

So for the original problem, both non-submit buttons should be written like this:

<button type="button" onclick="addItem()">Add Item</button>
<button type="button" onclick="removeItem()">Remove Last Item</button>

This is clearer and more robust than depending only on return false; in inline JavaScript.

Mental Model

Think of a form like a paper form on a clipboard.

  • A submit button is the button that sends the form to the office.
  • A normal button is just a tool on the desk, like “Add another page” or “Remove last line.”

If you place a button inside the form and do not label it, the browser assumes it is the send-to-the-office button.

So if you want a button that just performs an action on the page, you must label it as:

type="button"

Otherwise, the browser may try to send the form away.

Take Quiz

Syntax and Examples

The main syntax is simple.

1. Default behavior inside a form

<form>
  <button>Click me</button>
</form>

This button acts like a submit button.

2. Prevent form submission with type="button"

<form>
  <button type="button">Click me</button>
</form>

This button does not submit the form.

3. Submit button when you actually want submission

<form>
  <button type="submit">Submit</button>
</form>

Use this only for the real form submission action.

4. Better version of the original example

<form autocomplete="off" method="post" action="">
  <p>Title: <input type="text" /></p>

  <button type="button" onclick="addItem()">Add Item</button>
  <button type="button" onclick="removeItem()">Remove Last Item</button>

  <table>
    <tr>
      <th>Name</th>
    </tr>
    <tr>
      <td><input type="text" id="input1" name="input1" /></td>
      <td><input type="hidden" id="input2" name="input2" /></td>
    </tr>
  </table>

  <input id="submit" type="submit" name="submit" value="Submit" />
</form>

Why this works

  • Add Item is now just a normal button.
  • Remove Last Item is now just a normal button.
  • Only the final submit control sends the form.

5. Event-based prevention

Another common approach is preventing the default action in JavaScript:

<button id="removeBtn" type="submit">Remove Last Item</button>
document.getElementById('removeBtn').addEventListener('click', function (event) {
  event.preventDefault();
  removeItem();
});

This works too, but if the button is not supposed to submit at all, type="button" is usually the cleaner solution.

Step by Step Execution

Consider this small example:

<form>
  <button id="remove">Remove</button>
</form>

What happens when you click it?

  1. The browser sees a <button> inside a <form>.
  2. Because no type is given, it treats the button as type="submit".
  3. When the user clicks it, the browser starts the form submission process.
  4. If no code prevents that default behavior, the page submits or reloads.

Now look at this version:

<form>
  <button id="remove" type="button">Remove</button>
</form>

What happens now?

  1. The browser sees a button inside a form.
  2. This time, the button is explicitly marked as type="button".
  3. When clicked, it behaves like a regular UI button.
  4. No form submission occurs.

Trace with JavaScript

<form>
  <button type="button" onclick="sayHello()">Say Hello</button>
  <button type="submit">Submit</button>
</form>

<script>
  function sayHello() {
    alert('Hello');
  }
</script>

Step by step:

  • Click Say Hello

    • sayHello() runs
    • alert appears
    • form does not submit
  • Click Submit

    • browser submits the form

That separation is exactly what you want in real forms.

Real World Use Cases

Buttons that should not submit forms are very common in real applications.

Dynamic form builders

Examples:

  • add another email field
  • remove a phone number field
  • add a new address row

These buttons change the form structure, but should not send data yet.

Shopping carts

Examples:

  • increase quantity
  • decrease quantity
  • remove item

These actions often update the page or send AJAX requests, not a full form submission.

Admin dashboards

Examples:

  • preview settings
  • test API connection
  • generate slug from title

These are helper actions inside forms.

Multi-step forms

Examples:

  • validate current step
  • show more options
  • go back to previous step

Only the final action should submit the full form.

Data entry tools

Examples:

  • duplicate row
  • clear section
  • autofill values

These are interface actions, not submit actions.

Take Quiz

Real Codebase Usage

In real projects, developers usually combine correct HTML semantics with JavaScript event handling.

Common pattern: explicit button types

<button type="button" id="addBtn">Add</button>
<button type="button" id="removeBtn">Remove</button>
<button type="submit">Save</button>

This makes intent obvious.

Common pattern: attach events in JavaScript

document.getElementById('addBtn').addEventListener('click', addItem);
document.getElementById('removeBtn').addEventListener('click', removeItem);

This is cleaner than inline onclick because:

  • HTML stays simpler
  • JavaScript is easier to test
  • behavior is easier to maintain

Guard clauses

Your removeItem() already uses a guard-like pattern:

if (rows.length <= 2) {
  alert('Cannot remove any more rows');
  return;
}

This is common in real code because it stops invalid actions early.

Validation before submit

Developers often allow only one real submit path:

form.addEventListener('submit', function (event) {
  if (!isValid()) {
    event.preventDefault();
  }
});

All helper buttons remain type="button", while actual submission goes through validation.

Progressive enhancement

Good codebases ensure the form still behaves correctly even if JavaScript changes. Explicit button types reduce accidental submissions and make browser behavior more predictable.

Common Mistakes

1. Forgetting that <button> defaults to submit

Broken example:

<form>
  <button onclick="removeItem()">Remove</button>
</form>

Problem:

  • The browser treats it as a submit button.
  • removeItem() may run, but the form may submit afterward.

Fix:

<button type="button" onclick="removeItem()">Remove</button>

2. Relying only on return false in inline handlers

Example:

<button onclick="removeItem(); return false;">Remove</button>

This often works, but it mixes behavior into HTML and can be fragile in larger codebases. It is better to define correct button types first.

Better:

<button type="button" onclick="removeItem()">Remove</button>

3. Using type="submit" by accident

Broken example:

<button type="submit" onclick="addItem()">Add</button>

If the button is only for UI interaction, submit is the wrong type.

4. Preventing submit in JavaScript when simple HTML would solve it

Overcomplicated version:

document.getElementById('btn').addEventListener('click', function (e) {
  e.preventDefault();
  removeItem();
});

This works, but if the button should never submit, simply use:

<button type="button">Remove</button>

5. Confusing <input type="button"> and <button>

These are similar but not identical.

<input type="button" value="Remove" />
<button type="button">Remove</button>

Both can be non-submit buttons, but <button> is usually more flexible because it can contain richer content.

6. Not separating submit actions from UI actions

A form should usually have:

  • helper buttons with type="button"
  • one intentional submit control with type="submit"

Comparisons

OptionSubmits form?Best use caseNotes
<button>Yes, by default inside a formRarely safe without explicit typeBrowser treats it as submit
<button type="submit">YesReal form submissionUse for Save, Send, Submit
<button type="button">NoUI actions inside a formBest for add/remove/preview
<input type="submit">YesSimple form submissionOlder but still valid
<input type="button">NoSimple clickable buttonLess flexible than <button>
event.preventDefault()Prevents submission if used in event handlerWhen you need submit-like markup but custom behaviorUseful, but not a replacement for correct button type

type="button" vs return false

ApproachWhere it worksRecommended?Why
type="button"HTMLYesClear, semantic, browser-safe
return false in inline onclickInline handlersSometimesWorks, but mixes HTML and JS
event.preventDefault()JavaScript event listenersYesGood when handling events programmatically

Best rule

If a button is not supposed to submit the form, make it:

<button type="button">...</button>
Take Quiz

Cheat Sheet

Quick rule

Inside a <form>, a <button> defaults to:

<button type="submit">

To stop submission

Use:

<button type="button">Remove</button>

Button types

<button type="submit">Submit form</button>
<button type="button">Run JavaScript only</button>
<button type="reset">Reset form fields</button>

Safe pattern

<form>
  <button type="button" onclick="addItem()">Add Item</button>
  <button type="button" onclick="removeItem()">Remove Item</button>
  <button type="submit">Submit</button>
</form>

JavaScript prevention

button.addEventListener('click', function (event) {
  event.preventDefault();
});

Best practice

  • Use type="button" for helper actions
  • Use type="submit" only for real submission
  • Prefer event listeners over inline onclick in production code
  • Keep one clear submit path

Edge case to remember

If you omit type, browser behavior follows the default submit behavior for buttons inside forms.

FAQ

Why does a button submit a form even if I did not set type="submit"?

Because <button> inside a form defaults to type="submit" unless you explicitly set another type.

What is the easiest way to stop a button from submitting a form?

Set the button type to:

type="button"

Is return false enough to stop form submission?

It can work in inline handlers, but it is better to use type="button" for non-submit buttons and event.preventDefault() in JavaScript when needed.

Should I use <button> or <input type="button">?

Usually <button> is preferred because it is more flexible and easier to style, but both can be used for non-submit actions.

When should I use event.preventDefault()?

Use it when you are handling events in JavaScript and want to stop the browser's default behavior, such as form submission or link navigation.

Why did one browser seem to submit but another behaved differently?

Browser differences can appear due to event timing, DOM updates, and older implementations. Setting explicit button types removes this ambiguity.

Can I have multiple buttons inside one form?

Yes. Just make sure only actual submit actions use type="submit". Helper actions should use type="button".

Take Quiz

Mini Project

Description

Build a small dynamic form where users can add or remove item rows without accidentally submitting the form. This project demonstrates the difference between helper buttons and actual submit buttons inside a form.

Goal

Create a form with Add and Remove buttons that modify the form safely, while only the Submit button sends the form.

Requirements

  • Create a form with one text input for a title.
  • Add an Add Item button that appends a new row to a list.
  • Add a Remove Last Item button that removes the last added row.
  • Ensure neither helper button submits the form.
  • Keep one real submit button for sending the form.
Take Quiz

Keep learning

Related questions

View more