appendChild() checkboxes: remember selections with browser back button
Asked Answered
C

2

7

Thank you in advance to anyone who attempts to help me with this.

I have a form that I am adding checkboxes to via appendChild() - as selections for the user to chose from - based on a bunch of criteria.

When the user checks any of these boxes and then clicks the 'continue' button to post the selection to another page - and then clicks the back button - the checkboxes that were checked by the user - have now been forgotten by the browser (no longer checked).

If I use php to write the checkboxes or simply have static checkboxes - when the user checks any of these boxes and then clicks the 'continue' button to post the selection to another page - and then clicks the back button - the selected checkboxes are remembered (still checked)

My question is:

Why does the browser forget the selections the user made when I create the checkboxes with appendChild()

yet the same browser will remember the selections the user made when using static checkboxes

What is it about appendChild() that is not allowing the same browser to remember the checked selection?

[div id="mydiv"] here is where the checkboxes are going[div]


[script type="text/javascript"]

var newInput = document.createElement("INPUT");
newInput.id = "mycheckboxid";
newInput.name = "mycheckboxname";
newInput.type = "checkbox";

document.getElementById('mydiv').appendChild(newInput);

[/script]
Camass answered 23/11, 2012 at 18:7 Comment(5)
What browsers do you need to support?Public
All - is this a browser specific issue?Camass
wonder if this might help: #7957063Cask
Some browsers will cache the page in memory and just show it again when you press Back; some will reload it and re-run your JavaScript code (losing the user selections). I suppose the most portable way to preserve state between page reloads is to create a cookie that contains the checkbox state, and update it through JS whenever the user selects or deselects one. I'll see if I can find some sample code; in the meantime, you can read up on document.cookie.Public
Does each checkbox have its own ID? If so, this this might be what you're after: jsfiddle.net/bae5b. It stores the current checked state of each checkbox on the client's machine, and loads it back when the checkboxes are appended.Wedlock
P
6

The browser may "forget" dynamic changes to the DOM because different browsers use different strategies for caching web pages. When you hit the back button, the idea is that the browser can display its cached copy rather than re-request the page from the original web server.

It can accomplish this in (at least) two ways:

  1. The browser caches the DOM itself of a page upon leaving it. Upon revisit (forward or back) dynamic changes will persist.
  2. The browser caches only the original HTML of the page at load time (prior to any dynamic changes). This has the effect of losing those dynamic changes--further modification to the DOM with appendChild() or innerHTML is not recorded.

Note that some browsers additionally keep modified form data, and others do not. If your goal is 99+% compatibility across all browsers, then you have some work to do.

To work around this you need to persist the state somehow. You have a few options:

  1. Save data about the modifications to the page to localstorage. Use a key that is generated randomly on first page load and then kept in the page, so that the state changes will only apply to that instance of the page. On page load, if this key already exists, read the change data out and re-apply the changes. Older browsers do not support local storage.

  2. Do the prior thing with cookies. I don't recommend this, as it has the drawback of proliferating cookies. Cookies are sent and received in every request (including ajax ones), so you would be bloating the data being transmitted on every request. Old browsers would work fine with this.

  3. Abandon your dynamic change model and make the changes occur through a post to the server. Then the page will contain the modified html when pulled from the browser's cache. You probably don't want this, but I thought I'd point it out for completeness' sake.

  4. Save data about the modifications to the page via ajax behind the scenes to the server. This is not the same as actually round-tripping each change like the previous item. You still make changes dynamically, but you post an "advisement" file to the server. Then, on each page load, request any adjustment data from the server. This is similar to the first suggestion, but you are using the remote server as your storage. This makes extra net traffic occur on each page load, but the traffic can be minimal as it would be just about this page. It also makes extra net traffic occur that would not normally be sent (the advisement data). A clever system architecture, however, could use this information to persist a user's unsubmitted form data across computers and over time in a way that could be very handy (lets say your user does 199 out of a 200-question survey and then his power goes out--with this scheme he has a chance of painlessly continuing later exactly where he left off!).

  5. Make your Continue button open a new browser window, preserving the original page intact.

  6. Make your Continue button post the data without leaving the page, preserving it intact. You could do a simple lightbox-style overlay.

  7. If the lightbox-style overlay will not work but you really have to display a new page and don't want it to be in a new window, then redesign your site to work similarly to gmail: where pages change only through javascript, and only through using #hash tags at the end of URLs to control behavior. This can be difficult but there are libraries out there that can accomplish it. (For some browsers one has to resort to polling to see if the hashtag has changed.) The basic idea is that when you click a link that points to the same page but has a tag on it such as <a href="#about">About</a> the browser will initiate a page load event, and will push a new context into the history forward/back stack, but will not actually load a new page. You then parse the updated URL for the hash code (which maps to some kind of command) and carry it out. Through careful choice of the proper hash codes for each link, you can hide and display the appropriate page dynamically through Javascript and it will appear as if the person is navigating around a real web site. The reason you do all this is that, because the page never loads, you not only can maintain state in Javascript, you can maintain your DOM state as well--you simply hide the page that was modified by the user, and when the back event occurs that means to visit that page again, you display it, and it is exactly how the user left it. Advantage: If your site requires Javascript to operate, then you are not taking a risk by using even more Javascript to accomplish it. Disadvantage: Completely changing the architecture of your site is a LOT of work and can be difficult to get working on older browsers. To get started with this see Unique URLs. You might try out the jQuery hashchange plugin. If your web site has wide distribution you will want to be sure to address search engine optimization and web usability issues. You may want to see this SO page on detecting back button hash changes.

  8. Use the same strategy as in the prior point but instead of doing it with hashtags, use the new HTML5 history.pushState() and history.replaceState() methods--see Mozilla browser history.

If your goal is not 99% compatibility across 99% of the browsers in use, then please let us know what you are aiming at, as there may be a shortcut possible.

Update: added an option #8

Puseyism answered 23/11, 2012 at 20:59 Comment(4)
Thanks guys - It would be great if I could get a focused response to the question : Why does the particular browser "remember" the checkbox WHEN using static checkboxes - and "forget" the checkbox WHEN using appendChild() ?Camass
I believe I did provide you with a focused response to your question. Please see the sentence in the second paragraph above beginning "When the browser instead uses the original HTML...".Puseyism
So you are saying that the browser saves/caches the original HTML - previous to any dynamic changes. Is that correct? Do you think this is in effect the same things as using innerHTML += ? The browser has cached the static HTML, and by the time you make any change with innerHTML or appendchild() - the browser is done caching?Camass
That's my hypothesis, and it fits the known facts, but I can't prove it.Puseyism
A
0

Scripting pages doesn't stop at state management. It includes state management.

This means scripted state changes such as scripted page transitions(pages that internally navigate), content panes, popover menus , style changes and of course, form input and selections are all the responsibility of the scripter.

So, in answer to why .. it is because you did not manage the page state you scripted.

If you want your page to work as you seem to expect you can manage the page state changes you script yourself, use a js lib that manages page, or perhaps in your case form, state, or use the http(s) client/server state management and load up the session state, or in your case just the form state, at the server.

Alyssaalyssum answered 23/11, 2012 at 18:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.