328

I have a form that has a submit button in it somewhere.

However, I would like to somehow 'catch' the submit event and prevent it from occurring.

Is there some way I can do this?

I can't modify the submit button, because it's part of a custom control.

marco-fiset
  • 1,933
  • 1
  • 19
  • 31
Nathan Osman
  • 71,149
  • 71
  • 256
  • 361
  • 1
    You could still access the submit button. Render the page and grab its ClientID by viewing the page source. Then, using something like jQuery you could do something like $('#ctl01_cph01_controlBtn1').click(function() {return false;}); – rebelliard Jul 28 '10 at 05:59
  • 1
    @Rafael: True... but that would be a last resort - this is a very complex control. – Nathan Osman Jul 28 '10 at 06:00
  • 1
    @Raf that's asp.net based, and also not a best practice. But its essentially correct. I'd just avoid peeking at the source and using the control name, as it may change if someone edits the page. Unintended side effects and such. –  Jul 28 '10 at 11:40

11 Answers11

370

Unlike the other answers, return false is only part of the answer. Consider the scenario in which a JS error occurs prior to the return statement...

html

<form onsubmit="return mySubmitFunction(event)">
  ...
</form>

script

function mySubmitFunction()
{
  someBug()
  return false;
}

returning false here won't be executed and the form will be submitted either way. You should also call preventDefault to prevent the default form action for Ajax form submissions.

function mySubmitFunction(e) {
  e.preventDefault();
  someBug();
  return false;
}

In this case, even with the bug the form won't submit!

Alternatively, a try...catch block could be used.

function mySubmit(e) { 
  e.preventDefault(); 
  try {
   someBug();
  } catch (e) {
   throw new Error(e.message);
  }
  return false;
}
Saabbir
  • 588
  • 6
  • 8
Ben Rowe
  • 28,406
  • 6
  • 55
  • 75
  • 7
    Why not return `false` directly from `onsumbit`? – ProfK Mar 22 '13 at 09:02
  • 3
    You might want to show an error message to the user in the onsubmit. Fore example, "complete this mandatory field then submit". In that case event.preventDefault will come in very handy – Mark Chorley May 03 '13 at 09:26
  • 1
    @ProfK if you use event.preventDefault() it won't matter regardless, try/catch would just be part of your error handling – Ben Rowe Aug 29 '13 at 21:35
  • Your initial comment about having to watch out for a preceeding javascript error set me on the right track ... I'd forgotten to add a parameter in my jquery submit statement (ie. I had `$('form.foo').submit(function(){ ...` instead of `$('form.foo').submit(function(e){ ...` , and so the e.preventDefault was failing. – user1104799 Nov 08 '15 at 23:32
  • 13
    worked ... had to use the word event in brackets in firefox – danday74 Sep 17 '16 at 23:37
  • 7
    @BenRowe You Should add evt parameter to the called method. `(
    )` .Otherwise it gives Undefined error.
    – yigitt Jan 27 '17 at 10:21
  • if you then return true, after calling preventDefault, will the form submit? – user3494047 Apr 24 '17 at 16:34
  • 3
    I had to use the exact word `event` as parameter in Chrome, just if anyone's struggling with this.. – Sebastián Vansteenkiste Oct 18 '18 at 18:32
  • `e.preventDefault();` was the solution I needed. Thanks! – Jason Evans Jan 29 '19 at 09:34
  • This is my preferred solution because it is extensible in the scenario that I actually need to do other things in the `onsubmit` event, which is a common need, i.e. in this scenario it can be added to the beginning of whatever happens in the function. – cazort Nov 12 '21 at 20:54
  • Return false does not work at all, even in the absence of an error (Firefox 107). – Virus721 Nov 22 '22 at 16:03
157

You can use inline event onsubmit like this

<form onsubmit="alert('stop submit'); return false;" >

Or

<script>
   function toSubmit(){
      alert('I will not submit');
      return false;
   }
</script>

<form onsubmit="return toSubmit();" >

Demo

Now, this may be not a good idea when making big projects. You may need to use Event Listeners.

Please read more about Inline Events vs Event Listeners (addEventListener and IE's attachEvent) here. For I can not explain it more than Chris Baker did.

Both are correct, but none of them are "best" per se, and there may be a reason the developer chose to use both approaches.

gilad905
  • 2,842
  • 2
  • 16
  • 23
Reigel Gallarde
  • 64,198
  • 21
  • 121
  • 139
136

Attach an event listener to the form using .addEventListener() and then call the .preventDefault() method on event:

const element = document.querySelector('form');
element.addEventListener('submit', event => {
  event.preventDefault();
  // actual logic, e.g. validate the form
  console.log('Form submission cancelled.');
});
<form>
  <button type="submit">Submit</button>
</form>

I think it's a better solution than defining a submit event handler inline with the onsubmit attribute because it separates webpage logic and structure. It's much easier to maintain a project where logic is separated from HTML. See: Unobtrusive JavaScript.

Using the .onsubmit property of the form DOM object is not a good idea because it prevents you from attaching multiple submit callbacks to one element. See addEventListener vs onclick .

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
  • 2
    & for jquery: `$("button").click(function(e) { e.preventDefault() });` – Nixen85 Mar 20 '18 at 15:23
  • 6
    +1 dunno why all the other answers keep using inline onsubmits, since OP mentioned he can't change button (which means he probably can't change form either). Wondering if there's a way to get the 'form' if we have the button id – Robert Sinclair Jun 14 '19 at 03:32
  • 3
    Inline trash still the most voted, but thats not really the way of programming in JS since...2012? This Solution is THE solution. – Bakos Bence Feb 03 '21 at 19:22
  • 1
    I like most of this solution, but I avoid using `querySelector` because it returns the first element in the document matching the given selector. This can make your code break if a second form is later added earlier in the page, something that happens frequently, such as if you decide to later add a login form to the header, or even if an invisible or hidden form is added by a CMS module. (I've seen this happen on projects.) Using `getElementById` is more reliable because the ID *must* be unique, at least per DOM tree, according to HTML specifications, and validators will catch when it is not. – cazort Nov 12 '21 at 21:03
20

The following works as of now (tested in chrome and firefox):

<form onsubmit="event.preventDefault(); return validateMyForm();">

where validateMyForm() is a function that returns false if validation fails. The key point is to use the name event. We cannot use for e.g. e.preventDefault()

Vikram Pudi
  • 1,157
  • 10
  • 6
17

Try this one...

HTML Code

<form class="submit">
    <input type="text" name="text1"/>
    <input type="text" name="text2"/>
    <input type="submit" name="Submit" value="submit"/>
</form>

jQuery Code

$(function(){
    $('.submit').on('submit', function(event){
        event.preventDefault();
        alert("Form Submission stopped.");
    });
});

or

$(function(){
    $('.submit').on('submit', function(event){
       event.preventDefault();
       event.stopPropagation();
       alert("Form Submission prevented / stopped.");
    });
});
Sach
  • 554
  • 5
  • 14
8

For prevent form from submittion you only need to do this.

<form onsubmit="event.preventDefault()">
    .....
</form>

By using above code this will prevent your form submittion.

Lakhwinder Singh
  • 5,536
  • 5
  • 27
  • 52
Zuhair Taha
  • 2,808
  • 2
  • 35
  • 33
7
var form = document.getElementById("idOfForm");
form.onsubmit = function() {
  return false;
}
naikus
  • 24,302
  • 4
  • 42
  • 43
  • 2
    I think that using `.onsubmit` is a bad idea because it prevents you from attaching multiple `submit` callbacks to one element. I recommend using `.addEventListener()`. – Michał Perłakowski Dec 18 '15 at 02:33
  • 3
    Even if you have set an event handler via the property .onsubmit, you can still add additional handlers via .addEventListener(). The handler registered by the property will be invoked first then the ones registered with .addEventListener() in the order in which they were registered. – Daniel Granger Jan 02 '16 at 21:37
3

To follow unobtrusive JavaScript programming conventions, and depending on how quickly the DOM will load, it may be a good idea to use the following:

<form onsubmit="return false;"></form>

Then wire up events using the onload or DOM ready if you're using a library.

$(function() {
    var $form = $('#my-form');
    $form.removeAttr('onsubmit');
    $form.submit(function(ev) {
        // quick validation example...
        $form.children('input[type="text"]').each(function(){
            if($(this).val().length == 0) {
                alert('You are missing a field');
                ev.preventDefault();
            }
        });
    });
});
label {
    display: block;
}

#my-form > input[type="text"] {
    background: cyan;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="my-form" action="http://google.com" method="GET" onsubmit="return false;">
    <label>Your first name</label>
    <input type="text" name="first-name"/>
    <label>Your last name</label>
    <input type="text" name="last-name" /> <br />
    <input type="submit" />
</form>

Also, I would always use the action attribute as some people may have some plugin like NoScript running which would then break the validation. If you're using the action attribute, at the very least your user will get redirected by the server based on the backend validation. If you're using something like window.location, on the other hand, things will be bad.

Sebastián Palma
  • 32,692
  • 6
  • 40
  • 59
2

You can add eventListner to the form, that preventDefault() and convert form data to JSON as below:

const formToJSON = elements => [].reduce.call(elements, (data, element) => {
  data[element.name] = element.value;
  return data;

}, {});

const handleFormSubmit = event => {
    event.preventDefault();
    const data = formToJSON(form.elements);
    console.log(data);
  //  const odata = JSON.stringify(data, null, "  ");
  const jdata = JSON.stringify(data);
    console.log(jdata);

    (async () => {
      const rawResponse = await fetch('/', {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: jdata
      });
      const content = await rawResponse.json();

      console.log(content);
    })();
};

const form = document.forms['myForm']; 
form.addEventListener('submit', handleFormSubmit);
<form id="myForm" action="/" method="post" accept-charset="utf-8">
    <label>Checkbox:
        <input type="checkbox" name="checkbox" value="on">
    </label><br /><br />

    <label>Number:
        <input name="number" type="number" value="123" />
    </label><br /><br />

    <label>Password:
        <input name="password" type="password" />
    </label>
    <br /><br />

    <label for="radio">Type:
        <label for="a">A
            <input type="radio" name="radio" id="a" value="a" />
        </label>
        <label for="b">B
            <input type="radio" name="radio" id="b" value="b" checked />
        </label>
        <label for="c">C
            <input type="radio" name="radio" id="c" value="c" />
        </label>
    </label>
    <br /><br />

    <label>Textarea:
        <textarea name="text_area" rows="10" cols="50">Write something here.</textarea>
    </label>
    <br /><br />

    <label>Select:
        <select name="select">
            <option value="a">Value A</option>
            <option value="b" selected>Value B</option>
            <option value="c">Value C</option>
        </select>
    </label>
    <br /><br />

    <label>Submit:
        <input type="submit" value="Login">
    </label>
    <br /><br />


</form>
Hasan A Yousef
  • 22,789
  • 24
  • 132
  • 203
-4

Here my answer :

<form onsubmit="event.preventDefault();searchOrder(event);">
...
</form>
<script>
const searchOrder = e => {
    e.preventDefault();
    const name = e.target.name.value;
    renderSearching();

    return false;
}
</script>

I add event.preventDefault(); on onsubmit and it works.

yozawiratama
  • 4,209
  • 12
  • 58
  • 106
-4
<form v-on:submit.prevent="yourMethodHere">

The submit event will no longer reload the page. It runs your method.

From vue documentation: https://vuejs.org/guide/essentials/event-handling.html#event-modifiers

devugur
  • 1,339
  • 1
  • 19
  • 25
  • 1
    Please read [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer). While this code block may answer the OP's question, this answer would be much more useful if you explain how this code is different from the code in the question, what you've changed, why you've changed it and why that solves the problem without introducing others. – Saeed Zhiany Jun 25 '22 at 13:42
  • This question is not about Vue. Please update or remove this answer. – Sean Sep 02 '22 at 23:16