Input type="submit" Button onClick: jQuery replaceWith prevents form from submitting

64,378

Solution 1

According to the replaceWith() documentation:

The .replaceWith() method removes content from the DOM and inserts new content in its place with a single call.

When an element is removed, as per remove() documentation:

In addition to the elements themselves, all bound events and jQuery data associated with the elements are removed.

I'm assuming that is why the submit is not executing.

If you want the form to still submit you can manually trigger the submit after you have replaced the element.

DEMO - Submitting the form while replacing the button element

For readability, to demonstrate, I have moved the binding of the click event into script rather than in-line of the element. I also added an id in case of multiple forms, which is not really needed if you only got a single form as you can simply bind to $("form").on("submit") instead then

$("input[name='save']").on("click", function(){
    $(this).replaceWith('<img class="submit-form" src=http://www.example.com/images/ajax-loader.gif />');
    $("form").submit();
});

$("#myForm").on("submit", function(){
    alert("form has been submitted.");
    return false;
});

​Edit - Same code using in-line onclick

Moving the code into the in-line onClick still works.

Regarding the form submission, $(this) will be the button before it is replaced and be gone after, hence $(this).closest("form").submit() or any other form of selector using $(this) won't work.

You must target your form for submit neutrally without using $(this) by either using $("form").submit() or if you have mutiple forms use an id as in $("#myForm").submit().

<form id="myForm" action="http://jsfiddle.net/">
    <input class="button" name="save" type="submit" onclick="$(this).replaceWith('<img src=http://www.example.com/images/ajax-loader.gif />'); console.log(this); $('#myForm').submit();" value="SUBMIT">
</form>

DEMO - Submitting a form manually after replacing the button using inline onclick

As a side note, if you want the image to be displayed before the submit event is triggered you can apply a little trick like this:

$("input[name='save']").on("click", function(){
    $(this).replaceWith('<img class="submit-form" src=http://www.example.com/images/ajax-loader.gif />');

    // Makes sure the image is rendered before the submit executes.
    window.setTimeout(function(){
        $("form").submit();
    }, 300);
});

You can apply the same off course in your in-line onClick.

Solution 2

change your approach. Instead of remove button, try to hide it and append a new html element.

<input class="button" name="save" 
 onclick="$(this).hide(); $('<img src=http://www.example.com/images/ajax-loader.gif />').insertBefore(this);" type="submit" value="SUBMIT">

Solution 3

Say your form has id="myForm", then you can do the following:

<input class="button" name="save" onclick="$(this).replaceWith('<img src=http://www.example.com/images/ajax-loader.gif />');$('#myForm').submit();" type="submit" value="SUBMIT">
Share:
64,378
LOLapalooza
Author by

LOLapalooza

merge keep

Updated on July 19, 2022

Comments

  • LOLapalooza
    LOLapalooza almost 2 years

    I have the following HTML:

    <input class="button" name="save" onclick="$(this).replaceWith('<img src=http://www.example.com/images/ajax-loader.gif />');" type="submit" value="SUBMIT">
    

    When clicking on the button, the form no longer attempts to submit, but replaces itself with a turning AJAX loading gif and does nothing. If I remove the onclick portion, it submits.

    Long story, this is for a client, but I can't give them the same thing in the form of

    $(function() { $(input[name=save]).on({click:function() { $(this).replaceWith(...); } }); });
    

    Why won't this still submit after replacing itself? I'm not e.preventDefault()'ing anywhere.

  • LOLapalooza
    LOLapalooza over 11 years
    Sorry, when I said I can't put the script in that manner, I meant that due to some crazy restrictions, I MUST put it inline, not that it wasn't working like that. I'm trying to cook up some concoction of clicking on the button and doing something like $(this).closest('form').submit() but to my surprise it's still not working. Thanks for the info on the element being removed from the DOM, that makes sense.
  • Nope
    Nope over 11 years
    $(this).closest('form').submit() or any other form of selector using $(this) won't work. As you are still in the old element, the button, which you are replacing, $(this) will still point to the button but will no longer be there. The only way you can submit the form is by either select it by an id or simply use $("form") which may not be suitable if you got multiple forms. Even in my DEMO when the code is not inside an onclick that doesn't work for those reasons.
  • Nope
    Nope over 11 years
    @LOLapalooza: I edited my post with a DEMO using the in-line onClick. Also, have a look here for the benefits of not using in-line onClick: Why is using onClick() in HTML a bad practice? Not sure on the "restrictions" but it seems a great benefit to have your code separated from the HTML, testable and unobtrusive causing HTML to be clutter-free and so on.
  • LOLapalooza
    LOLapalooza over 11 years
    Thanks, this worked wonderfully. I always avoid in-line onClicks when possible but this particular client has some weird restrictions on their server from the IT department. They have to make content in an iframe, and can't put in <script> tags anywhere, but are allowed to use inline javascript. I don't understand, but it's an argument they've lost many times.