112

There seems to be lots of info on how to submit a form using javascript, but I am looking for a solution to capture when a form has been submitted and intercept it in javascript.

HTML

<form>
 <input type="text" name="in" value="some data" />
 <button type="submit">Go</button>
</form>

When a user presses the submit button, I do not want the form to be submitted, but instead I would like a JavaScript function to be called.

function captureForm() {
 // do some stuff with the values in the form
 // stop form from being submitted
}

A quick hack would be to add an onclick function to the button but I do not like this solution... there are many ways to submit a form... e.g. pressing return while on an input, which this does not account for.

Ty

1

5 Answers 5

121
<form id="my-form">
    <input type="text" name="in" value="some data" />
    <button type="submit">Go</button>
</form>

In JS:

function processForm(e) {
    if (e.preventDefault) e.preventDefault();

    /* do what you want with the form */

    // You must return false to prevent the default form behavior
    return false;
}

var form = document.getElementById('my-form');
if (form.attachEvent) {
    form.attachEvent("submit", processForm);
} else {
    form.addEventListener("submit", processForm);
}

Edit: in my opinion, this approach is better than setting the onSubmit attribute on the form since it maintains separation of mark-up and functionality. But that's just my two cents.

Edit2: Updated my example to include preventDefault()

Sign up to request clarification or add additional context in comments.

9 Comments

this does not work with chrome either as far as i can see using jsbin.com/ejoyas
Note that the attach event code needs to be executed AFTER the form is available in the dom. For example using window.onload=function() { ... } to wrap it
when does the processform() function gets called sir?
Not sure because I don't use IE, but I think the attachEvent parameter should be "onsubmit".
in 2017, check for addEventListener before falling back to attachEvent since IE9+ supports addEventListener.
|
44

You cannot attach events before the elements you attach them to has loaded

It is recommended to use eventListeners - here one when the page loads and another when the form is submitted.

NOTE: NEVER call anything in a form "submit"

This works since IE9:

Plain/Vanilla JS

// Should only be triggered on first page load
console.log('ho');

window.addEventListener("DOMContentLoaded", function() {
  document.getElementById('my-form').addEventListener("submit", function(e) {
    e.preventDefault(); // before the code
    /* do what you want with the form */

    // Will be triggered on form submit
    console.log('hi');
  })
});
<form id="my-form">
  <input type="text" name="in" value="some data" />
  <button type="submit">Go</button>
</form>

jQuery

// Should only be triggered on first page load
console.log('ho');

$(function() {
  $('#my-form').on("submit", function(e) {
    e.preventDefault(); // cancel the actual submit

    /* do what you want with the form */

    // Will be triggered on form submit
    console.log('hi');
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form id="my-form">
  <input type="text" name="in" value="some data" />
  <button type="submit">Go</button>
</form>

Not recommended but will work

If you do not need more than one event handler, you can use onload and onsubmit

// Should only be triggered on first page load
console.log('ho');

window.onload = function() {
  document.getElementById('my-form').onsubmit = function() {
    /* do what you want with the form */

    // Should be triggered on form submit
    console.log('hi');
    // You must return false to prevent the default form behavior
    return false;
  }
}
<form id="my-form">
  <input type="text" name="in" value="some data" />
  <button type="submit">Go</button>
</form>

3 Comments

I think you mean: $('#my-form).on('submit', function() { alert('hi'); });
@Michiel while what you provide is what you use with jQuery, this solution provided is a pure JS solution with no dependency on jQuery. The solution here would similar to using <form onsubmit="alert('hi'); return false;">
@ChrisMarisic - a few years old :) I have updated the answer anyway to include jQuery
22

<form onSubmit="return captureForm()"> that should do. Make sure that your captureForm() method returns false.

8 Comments

Follow up: Is there a way to capture a form submit with JavaScript without affecting the browser's handling of the required attribute?
@Elisabeth What handling of what attribute? If you mean to not prevent the form from actually being submitted, you just need captureForm() to return true instead of false.
The browser's handling of the "required" attribute. I do want to prevent the form from being submitted. But by returning false instead of true (or using preventDefault()), it changes how the browser handles the "required" attribute on an input element. Try it for yourself: add <code>required</code> to an input element, capture the submit and see if you lose the default behavior for it.
I don't seem to lose default behaviour. It works fine in Chrome. You'll need to come up with an erroneous example in order for me to help.
Ok, here's the form: <form method="get" action=""> <label for="color">What is your favorite color?</label> <input type="text" name="color" placeholder="blue" required> <input id="submit" type="submit" value="Submit"> </form> and here's the code: function processForm(e) { var form = document.querySelector("form"); for (var i = 0; i < form.childNodes.length; i++) { var node = form.childNodes[i]; /* do stuff with nodes / } / return false; */ } Testing in opera. Uncomment the last line, required fails. (Sorry code doesn't work well in comments)
|
5

Another option to handle all requests I used in my practice for cases when onload can't help is to handle javascript submit, html submit, ajax requests. These code should be added in the top of body element to create listener before any form rendered and submitted.

In example I set hidden field to any form on page on its submission even if it happens before page load.

//Handles jquery, dojo, etc. ajax requests
(function (send) {
    var token = $("meta[name='_csrf']").attr("content");
    var header = $("meta[name='_csrf_header']").attr("content");
    XMLHttpRequest.prototype.send = function (data) {
        if (isNotEmptyString(token) && isNotEmptyString(header)) {
            this.setRequestHeader(header, token);
        }
        send.call(this, data);
    };
})(XMLHttpRequest.prototype.send);


//Handles javascript submit
(function (submit) {
    HTMLFormElement.prototype.submit = function (data) {
        var token = $("meta[name='_csrf']").attr("content");
        var paramName = $("meta[name='_csrf_parameterName']").attr("content");
        $('<input>').attr({
            type: 'hidden',
            name: paramName,
            value: token
        }).appendTo(this);

        submit.call(this, data);
    };
})(HTMLFormElement.prototype.submit);


//Handles html submit
document.body.addEventListener('submit', function (event) {
    var token = $("meta[name='_csrf']").attr("content");
    var paramName = $("meta[name='_csrf_parameterName']").attr("content");
    $('<input>').attr({
        type: 'hidden',
        name: paramName,
        value: token
    }).appendTo(event.target);
}, false);

Comments

1

Use @Kristian Antonsen's answer, or you can use:

$('button').click(function() {
    preventDefault();
    captureForm();
});

3 Comments

for anyone else doing this 2.5 years (or more) later, you need to pass the click event as a parameter to the function (as in function(e) and call e.preventDefault()
Can also be captured on the "submit" event for the form, if your input[type="submit"] is used, and that puts you in the form context versus the context of the button. The callback will always have the context of the event, so you do not necessarily have to pass 'e' as an argument, you simply refer to 'event'.
This is not recommended, as submission can be triggered be a keypress.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.