Young Young - 1 month ago 8
HTML Question

jQuery .replaceWith() method refreshes on click

I am using jQuery .replaceWith method to enable users to reply or cancel commenting on a post. The reply button works as it creates a text box when clicked. However, clicking the cancel button refreshes the page instead of going back to the original post without page reload. How can I make the cancel button function properly? Thank you for your help!

<form method="post">
<input type="hidden" name="post_id" value="{{ p.key.id() }}">
<input type="hidden" name="user_id" value="{{ user.key.id() }}">
<input type="button" name="reply" id="{{ p.key.id() }}" value="Reply">
</form>

<script>
$("#{{ p.key.id() }}").click(function() {

var reply = $("<textarea name='reply_content' style='resize: none; width: 550px; height: 100px;'></textarea><br><input type='submit' name='reply' value='Reply'><input type='submit' id='cancel_{{ p.key.id() }}' value='Cancel'>")

$("#{{ p.key.id() }}").replaceWith(reply);

});

$("#cancel_{{ p.key.id() }}").click(function() {

var cancel = $("<input type='button' name='reply' id='{{ p.key.id() }}'' value='Reply'>");

$("#{{ p.key.id() }}").replaceWith(cancel);

});

</script>

Answer

EDIT: Now that I know more information, I'm updating my old answer.

New Answer:

I looked over the code and realized that there were a couple of things going on. The first was a delegation issue which occurs when you tie an event to an object and then remove it from the DOM which is what is happening with that replaceWith. You can read more about delegation here:

https://learn.jquery.com/events/event-delegation/

The second issue is that you made your buttons submit. Because of this, the form was trying to POST to the SS and thus the refresh. In the JS fiddle below; I have changed them to buttons but if you require the submit, you can just use e.preventDefault to prevent the form from submitting.

The third issue was what I believe you trying to hide the textarea and reply buttons on the cancel button click. This didn't work because you would have replaced the reply button and not the entire form itself which caused the buttons to change but the textarea to persist.

Now I'm sure there are cleaner ways of doing it on jsFiddle but I'm hoping this got the point across with what was going on.

The fixes that I applied was to save the original state (for the cancel button to go back to), fix the buttons and events, and change the cancel button to just repopulate using the original state.

EDIT 2: I forgot to attach the new fiddle!

https://jsfiddle.net/6s03k0eb/5/

OLD Answer:

So there are a couple of things going on here. First The below is an invalid HTML ID

<input type="button" name="reply" id="{{ p.key.id() }}" value="Reply">

Id's can't start with a number and should most definitely not contain brackets. If this id, is being populated by the server then you definitely need to update the jQuery with the proper ID and not the server side variable:

Incorrect

  $("#{{ p.key.id() }}")

Correct

  $("#someID")

The reason your page keeps on refreshing is because you have a JS error due to the invalid jQuery selector so the button does its default action which is to submit the form.

Here is a JS fiddle showing the code working with the proper ID values: https://jsfiddle.net/6s03k0eb/