Question

I have a plain vanilla form with id="edit_profile".

When the form is submitted I want to intercept it and check whether I need to geocode an address via the google maps api, and if not go ahead and submit anyway.

Something like:

$('#edit_profile').on('submit', function(event) {
    event.preventDefault();
    if ( some test ) {
        geocode_address( address, this ); // the api callback will handle form submit
    } else {
    // we want to go ahead and submit the form
    this.submit();
    }
});

The problem is this.submit() is throwing the error TypeError: Property 'submit' of object #<HTMLFormElement> is not a function

I read something recently but can't now find about having to use native JavaScript to submit the form rather than jQuery (I'm guessing because the jQuery event handler for the form submit has already been told to preventDefault).

But if I try some variant like document.getElementById('edit_profile').submit(); or document.forms[0].submit(); I get the same error or thereabouts.

Was it helpful?

Solution 2

I'm answering my own question because the solution was so unexpected and simple it bears repeating. Full credit to Chris Butler for answering this related question: Unable to `submit()` an html form after intercepting the submit with javascript (note, his wasn't the accepted answer).

Answer: if you name & #id your submit buttons "submit" that will clash with the name of the native JavaScript .submit() method which will no longer work and give the type error described in the question.

So the solution in my case was to rename my submit button to something else.

To recap:

To intercept a form submission you could intercept the click on the submit button or intercept the form submission itself. If your objective is to intercept the form submission then do that, not the click event on the submit button, as forms can be submitted by other events such as hitting enter on a textfield.

If you intercept the form via jQuery with, e.g. $("#myForm").on("submit", function() {...}) and then go on to pass off the submit handling to another function (e.g. as in the question where a call to a geocoding api is made) then that function will need to trigger the form submission via acting on the DOM form element directly (e.g. `document.getElementById('myForm').submit() ) which will submit the form without triggering the onsubmit event so that the initial intercept isn't triggered again creating an infinite loop as it would be if you used jQuery to trigger the submit.

OTHER TIPS

DOM Elements have no method .submit -- but jQuery objects do (only on form elements) -- basically, you forgot to wrap this in jQuery:

$(this).submit();

Ref: https://api.jquery.com/submit/

Edit:

I see where you are getting the "infinite-loop" scenario from. You should actually be setting the handler up to trigger when you click the Submit button and not the forms actual submit.

As of now, you catch the forms submit action and prevent the default action (which is submitting) -- then you do some stuff and call submit on this. Well that will trigger the handler for the form submit, which prevents the default action again! So, in short, put a handler on your Submit button, prevent the default action, do logic, then call $("#edit_profile").submit()

Why not rearrange the code something like this

$('#edit_profile').on('submit', function(event) {
  if ( some test ) {
    event.preventDefault();
    geocode_address( address, this ); // the api callback will handle form submit
  } else {
    // we want to go ahead and submit the form
    // this.submit(); // no need to call explicitly
  }
});

It won't work, if you want to have callback in some test but it doesn't look like that from your code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top