How can I "reset" <div> to its original state after it has been modified by JavaScript?
Asked Answered
M

10

47

I have a DIV with a form in it. When users submit the form and it gets successfully submitted, I replace the form with a simple "everything is good now" message:

$("#some_div").html("Yeah all good mate!");

Is there a good way to "reset" the div to its "original state" as per the HTML it has arrived with? I can only think of actually doing something like this:

//before I change the DIV
var originalState = $("#some_div").html();
//manipulate the DIV
//...
//push the state back
$("#some_div").html(originalState);

It doesn't look very elegant - I guess there is a better solution for this, no?

Mocha answered 5/4, 2011 at 19:49 Comment(2)
I think what you've shown there is the best way to go about it. Once you set the HTML of an element, it's previous content is destroyed. So you have to store it yourself before you destroy it.Lemur
html() rewriting is nonsense. Just use show() and hide() to toggle the display of the form and message elements.Crumbly
P
93

I would clone the element, instead of saving the content. Then use replaceWith to restore it:

var divClone = $("#some_div").clone(); // Do this on $(document).ready(function() { ... })

$("#some_div").html("Yeah all good mate!"); // Change the content temporarily

// Use this command if you want to keep divClone as a copy of "#some_div"
$("#some_div").replaceWith(divClone.clone()); // Restore element with a copy of divClone

// Any changes to "#some_div" after this point will affect the value of divClone
$("#some_div").replaceWith(divClone); // Restore element with divClone itself
Pray answered 5/4, 2011 at 19:57 Comment(4)
did not knew about replaceWith, very nice!Cantu
On the last step you have, is there a way to NOT change the value of divClone?Hustle
This doesn't clone the event listeners, tested hereHandbreadth
cloning will remove all the jquery event functionalities.Catima
K
21

You can use the data attribute to save the state rather than a variable

$('#some_div').data('old-state', $('#some_div').html());
$('#some_div').html($('#some_div').data('old-state'));
Knifeedged answered 5/4, 2011 at 19:56 Comment(1)
I used this with AJAX and dynamically created buttons, and this was the only answer that worked for me.Possible
A
5

What you're doing is not optimal. The best solution would be this:

When the form gets successfully submitted, just hide() the FORM element, and show() the message (which is initially hidden). And then, later, just show() the FORM element and hide() the message.

Asaasabi answered 5/4, 2011 at 20:2 Comment(9)
Mmmm, how much more beneficial is this? I mean - why is this not optimal - how much is show/hide better?Mocha
@Mocha Writing your FORM element into a string will destroy all event handlers that are bound on that form or any of its ancestor elements (like form fields). All other changes that were done programmatically on the form element or any ancestor will be lost too. HTML rewriting is a horrible idea.Crumbly
@ŠimeVidas what is your thought on using .clone(true, true) which will also clone data and event handlers, and will also do that for all children of the cloned element(as per jQuery API doc)?Formate
@jj_ In what context?Crumbly
concerning the use case the OP was facing, or as in you example, in case might you want to clone a FORM element.Formate
@jj_ If OP wants to temporarily display a message instead of the FORM element, he can use .show() and .hide() on those elements. Creating clones for this is senseless. There is no reason do do such an expensive operation in this case.Crumbly
I know already your point of view on what is the most optimal way to do this. You already stated it. I am just questioning you on wheter, in case OP or I wouldn't want to change the initial approach, the .clone(true,true) method would have worked for the purpose of avoiding the downfalls of writing an element in a string (which you've illustrated: loosing all event handlers and the rest).Formate
@jj_ I did a quick test: jsfiddle.net/simevidas/WUU9k Results: The bound event handler persists, but the user-entered content in the form fields does not persist. (Enter some text in the second text field and it won't persist).Crumbly
The main idea though, is extensibility. Using .clone() and .replaceWith(), you can just instantiate a template DOM node then update the template instances as you need to, instead of statically duplicating different permutations of subnodes and toggling show/hide.Batter
M
4

Yeah, the way you have is the way to do it. The DOM does not save the previous states of DIVs, so you need to save that yourself.

Machinegun answered 5/4, 2011 at 19:55 Comment(0)
S
4

In my opinion best is to use this:

var originalState = $("#some_div").clone();
$("#some_div").replaceWith(originalState.clone());

This way you can repeatedly use this to restore your div to original state while keeping the data in "originalState" intact. Worked for me.

Spurn answered 9/9, 2016 at 7:6 Comment(0)
B
2

You have basically three options.

  1. Remember your original markup, as you do with your originalState variable above.
  2. Use AJAX to re-request the markup. You can do this easily if you have server side code using the $.ajax() method in jQuery.
  3. Cause the page to reload.
Bit answered 5/4, 2011 at 19:56 Comment(0)
P
2

Somewhat more elegant?

var originalState = $("#some_div").clone();
$("#some_div").replaceWith(originalState);
Pyromania answered 5/4, 2011 at 19:59 Comment(0)
H
2

Making call to empty function in jQuery will do it

$(".div").empty();
Hadwin answered 22/10, 2018 at 16:1 Comment(0)
U
0

This is my very first interaction on this site--I can't comment yet, but this is to @Fleuv's comment on @Josiah Ruddell's answer:

The default parameter for .clone() is "false", which will not clone event listeners. If you make it .clone(true) it clones the event listeners as well. I've tested it (with the rest of his answer) and it works.

w3schools jQuery clone() method

Unilateral answered 2/3, 2019 at 18:21 Comment(0)
G
0
var originalState = $("#some_div").clone(true, true);
$("#some_div").replaceWith(originalState.clone(true, true));
Ginger answered 23/9, 2019 at 9:44 Comment(1)
May be your answer is correct. but this will consider as LOW QUALITY answer as it's contain only code. Please add some explanation covering how this will resolve an issue.Foust

© 2022 - 2024 — McMap. All rights reserved.