Hews
Hews

Reputation: 581

AJAX back button

I've been reading about history.pushState and popstate but for a web-page that's populated with mostly AJAX requests (say a book store that allows users to add items to a cart), is there a function with the history object or something similar, that can rewind these additions?

A simpler representation of this is in the below example. A user clicks on a div and "Shown" appears in the respective div. Below these divs is the text, You have selected [detail]. This changes with respect to the selection and triggering the popState changes the text in the right way.

But the divs still have "Shown". Is there a way to remove these in order as they were added similar to how the line of text changes, or do I have to create a separate function to take care of this - which would be the opposite of the function that added "Shown" to the div?

I've added some function that I've edited in to achieve the above but I just don't like how hacky it is.

<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">

</head>
<body>

<div class='name'></div>
<div class='age'></div>
<div class='sex'></div>

<p>You have selected <span>no color</span></p>

</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js">
</script>

<script>

$('div').on('click', function() {

var detail = $(this).attr('class');

showDetails(detail);
doPushState(detail);

});

function showDetails(detail) {
var classDeets = '.'+detail

$(classDeets).text("Showing " + detail);
$('p span').text(detail);

}

function doPushState(detail) {

var state = { selected : detail },
  title = "Page title",
  path = "/" + detail;

  history.pushState(state, title, path);
}

function removeDetails(detail) {

var classDeets = '.'+detail

$(classDeets).text("");
}

function checkState(detail) {

var temp = document.getElementsByClassName(detail)[0].innerHTML;

if(temp.length == 0){
  showDetails(detail);
}
else{
  removeDetails(detail);

 }

}

$(window).on('popstate', function(event) {

var state = event.originalEvent.state;

if (state) {
  checkState(state.selected);
}
});

</script>

Upvotes: 0

Views: 144

Answers (2)

Veritoanimus
Veritoanimus

Reputation: 319

I'm not sure exactly what your use case is, but I immediately think of ajax loaded report and list pages that I do. I encode the options for the report after a "#". It makes the browser buttons work as intended for updating url based and it makes it linkable to others. You then just need to poll the # encoded data to detect changes and update accordingly. Since you use the # (in page link) it doesn't trigger a page load to the server. You just have to make sure that if you use encoded hash data that you don't use in-page links for page navigation. If this sounds like an option, let me know and I can post some helper code for setting it up.

Upvotes: 1

shagamemnon
shagamemnon

Reputation: 79

Without more context, it's tough to rewrite your code. That said, you need to use history.replaceState() instead of history.pushState().

history.replaceState() modifies the state of a history entry. From MDN: "replaceState() is particularly useful when you want to update the state object or URL of the current history entry in response to some user action."

Upvotes: 0

Related Questions