3

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
  • 2,042
  • 3
  • 17
  • 22

3 Answers3

6

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.

Nope
  • 22,147
  • 7
  • 47
  • 72
  • 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. – LOLapalooza Nov 27 '12 at 22:25
  • 1
    `$(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 Nov 27 '12 at 22:37
  • @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?](http://stackoverflow.com/questions/5871640/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. – Nope Nov 27 '12 at 22:53
  • 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 – LOLapalooza Nov 28 '12 at 14:21
1

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">
mccannf
  • 16,619
  • 3
  • 51
  • 63
1

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">
Luca Rainone
  • 16,138
  • 2
  • 38
  • 52