Back button handling in Single Page Apps? - javascript

A similar question here has been noted!
I've got an SPA based exclusively on the DHTMLX toolkit (fabulous stuff incidentally). One serious UX problem is with back button handling: there is none.
Their forum recommended 'any js routing library to handle state of the app in the url hash and restore it back'.
I am confused by this as the SPA has only the simplest HTML, is exclusively Javascript and does most communicating via WebSockets ... does this mean I have to store state on each button click/keypress?
So, ...
Does the panel have any recommendations on best practices?
Is there an existing library that will do this?
If said library is light on examples, can anyone provide a basic how-to?
Many thanks

Dhtmlx is a great framework for building SPAs. Like all SPAs, the back button will simply take the user right out of app. Also the user cannot bookmark anything.
So what you want to do is use javascript's pushState() which will allow you to control the url.
For example, suppose you show a search screen to go to a record. The user enters the search criteria and presses search. You bring in the results via ajax and update a grid. Then the user selects the row and you go to a detail page (typical search functionality here).
At this point, you would want to use pushState() to change the url to something like:
http:/me.com/search/23432
This will allow the user to bookmark the page. Then when the user leaves the detail page, use pushState() and set the url to http:/me.com/search
So you have complete control over the url.
The next thing you need to learn is popState(). This function is called when the url changes. So suppose the user pushes the bookmark to go to "23432". popState() will be called and you'll react accordingly.
That's basically it in a nutshell: pushState() and popState().
Some older browsers do not react to pushState/popState. There are libraries floating around to handle older browsers using url hashing. I am not too familiar with them as I am only supporting html5 browsers.

Related

How do I open a Modal after a successful Oauth2 redirect?

I'm working on a relatively old web application, based on portal/portlet architecture.
I have an ingress on the application which loads my feature in a Modal. Currently we have navigation built into the modal where we show and hide divs if customers move back and forth and update our ingress with Javascript once the interaction ends.
Now we want to introduce another card inside the modal which requires the customer to access sensitive data, therefore we want the customer to authenticate again.
We have an OpenId OAuth2 Authentication provider that we call with a callback URL. Currently this callback URL is the URL for the main page, therefore the customer is taken out of our modal experience and we have a high likelihood of engagement drop-off. We'd want to be able to get them back into the Modal experience where they'd left off before authenticating.
Are there some common strategies or patterns that can help achieve this? One thing that might work is if we are able to pass in a javascript method as a part of the redirect url too.
I can't make any changes to the underlying container but have freedom to add javascript events and handlers.
You could use the state parameter in the OAuth2 request.
From RFC 6749:
the client MAY use the "state" request parameter to achieve
per-request customization
Then when you get the state value back in the response, you could open the modal with your additional card. The state value is a string value and could include what you wanted. Just make sure to not forget to cover CSRF.
https://www.rfc-editor.org/rfc/rfc6749#section-3.1.2

Zapier webhook url alternative

We are using zapier's webhooks to collect answers we gather via html5 formatted mail messages. The mail is created with zapier and includes some dynamic info and two buttons to make your choice. These button actions are each linked to a different webhook. The webhook provided by zapier has a static part and a dynamic part which is a zapier variable. When the receiver pushes the button, a blank browser window shows up with, whether a short text or in "silent mode" a blank page.
Although we are sending an extra mail as confirmation for the decision made via mail, we would like to either avoid the showing of this blank page at all or maybe replace it by a customized HTML page that shows a more attractive web page.
We tried different approaches like using an additional javascript onlick action on the button to achieve the opening of two pages with one click. One with the webhook blank page as the trigger and another one with a nice confirmation message page for a nice user experience. Unfortunately, there are some mail client limitations that seems not to allow javascript executions.
Is there any workaround like using any third-party service that offers webhook containers with the possibility to customize the content of the page linked to the webhook URL or any idea on how to link a button action to two url’s?
Thank you for reading this long question. Any help would be greatly appreciated.
David here, from the Zapier Platform team.
I can't speak to other options, but the best choice for you here is probably to have the email link go to a static page with two buttons. That way, you'll be in the browser and can do whatever you need with JS. This is likely buttons that have onClick handlers and then show nice confirmations.
It also avoids false clicks, where a mail client tries to load external resources (which normally doesn't matter, but in this case can trigger a webhook).

Custom back button based on history

In my one-page web app, I would like to have a back button on some of the pages that takes the user back to a specific point in their browser history: not necessarily the previous page.
Note that I am not talking about the browser's back button, which should work as usual.
Use Case
For an example, consider the gmail web app. There is a folder view, potentially with search filters or other parameters, and then a message view that shows a single message. In the messages view, there is a back button that does not take you to the previous page: even if you have clicked around reading several messages, the back button will take you back to the folder view from which you originally came before clicking on any of the messages.
In the case of gmail, this is achieved by simply encoding the previous state at the end of the URL. E.g., if you got to this message by searching, it will be:
#search/stuff/<MESSAGE_ID>
From this, the app knows that the back button should point to the page with:
#search/stuff
In my application, however, there is too much state to encode it all in the URL. Rather than two views (folder + message), there are three views, let's call them A, B, and details, with both A and B having a wide array of possible filters and options encoded in the URL that I would like to preserve when e.g. returning from B to A or from details to B. Encoding all the parameters for A, B and details in the URL of the details page would make the URL extremely unwieldy.
Implementation
I thought this could be easily achieved using the html5 history API. However, as far as I can see the history API does not provide support for reading the URLs in the history: you can only blindly go back or forward.
history.js provides access to past states, as discussed in a related question:
History API: Javascript Pushstate, get previous URL
However, I am using angularjs which does not work well with history.js, because it talks directly to the history api instead of going through history.js, so the states from transitions caused by the angular $location service do not show up in history.js' History object.
It seems that what I would need to do one of the following:
get history.js to work well with angular
re-implement a subset of history.js' functionality in my own code
I also considered using document.referrer to peek at the previous value in history, but that does not work as it does not get set when navigating within a one-page app.
Answering my own question, I chose to go for the simpler solution suggested by #MaxArt in his comment.
Generate a random ID for a page
Since I use angularjs, I do this $on('$routeChangeSuccess') or $on('$routeUpdate')
without angularjs, I suppose I would do this onpopstate
Store a mapping from this random ID to all the URL information that I need (in my case, search and path) in sessionStorage
Include a search parameter from=the ID of the current page in outgoing links that go forward in the conceptual hierarchy of my app
When the custom back button is clicked, look up the state I come from in sessionStorage using the from seach parameter
if found, go back to that URL
if not found (user navigated to this page directlry), go back to the default URL for the previous view in the app's hierarchy
Rationale for taking this approach over the more general approach of building a history of past URLs:
As mentioned, the pushState API does NOT provide access to past URLs
Integrating History.js, which does provide that information, into angularjs does not seem trivial
angularjs uses the history API internally: it would need to be changed to instead use History
Implementing custom code to record the URL history in sessionStorage is also not trivial. The main problem is that, lacking integration with the browser's history, there does not seem to be a general way to know if a visited page is new or it was reached by going back one or more steps in the browser history. I'd be happy to be corrected on this if someone can suggest a solution (1)
Using History.js or any equivalent solution that wraps all history.pushState with additional code, requires pretty much all links on the page to be wrapped in History.pushState, otherwise URL changes do not show up in the History.
(1) How do I retrieve if the popstate event comes from back or forward actions with the HTML5 pushstate?
I've never worked with angular.js, but presumably window.history.pushState is what you're looking for if you want something guaranteed to work. Have a read-over of http://spoiledmilk.com/blog/html5-changing-the-browser-url-without-refreshing-page/ for the detailed information on what this baby can do.

How to create a guided tutorial for a web-page using JavaScript?

Certain websites (notably Facebook games) have a step by step tutorial for new users, where JavaScript is used to create a pop-up which tells the user where to click next and what is happening.
How does one create such a system? What sort of architecture is required?
I suppose that a script is loaded if a flag is a tutorial flag is set, and that stored within the user's state there's a 'pointer' which indicate which step in the tutorial the user is at. That script would echo out the relevant JavaScript for pop-ups and highlight and whatever.
The question, I guess, is how does one detects when the user has performed the required action and that the tutorial is to proceed to the next step?
On Edit : The 'action required to proceed to the next step' could involve the user clicking on a link itself, or submitting a value through a form. So the state must be able to persists and the script must be able to detect interactions on different UI elements throughout the page.
I think solution will depend on which technologies you are using.
Simply - you can store user's tutorial progress in a cookie file, and on each his action (e.g. button click) call javaScript handler, which will update it's status.
You can prototype your tutorial as Finite State Machine. I think this tutorial data presentation will be very helpful.

Using Javascript back function after POST form submit

In my web application, I'm providing a link, clicking on which goes to another page, shows some data,popups a page and goes back using javascript back() function.
It was working fine but it fails in certain cases. For example, this link appears after a form submission also. When the back() function is called here, the Webpage Expired message is shown because it was a POST operation.
How can I go back to the previous page using javascript in this situation?
Please provide your inputs...
You can't do anything about page expiration from JavaScript - that's how the browser opts to protect the user from re-submitting the form accidentally.
You could use the POST/Redirect/GET approach, depending on how your application works, to ensure users always land on a GET after submitting their form, so you always have a valid state to go back to.
To be honest, 99% of the time using the back() functionality in JavaScript is an indication something's wrong in the underlying approach. It's just too fraught with problems to be workable, as you're seeing here. You might get further if you start a new question to describe what you're trying to accomplish. There's a lot of really smart people around here who can all put their heads together and help you come up with something.
Can you explain why you need to navigate to the previous page using client-side script? I'm assuming it's because the user may be arriving at this page from various other pages and you want to direct them back to the page they came from. You could always store the user's previous page URL in a session or cache object and direct them back to that URL in server-side code. Or, if you know where they will always be coming from, direct them back to a static URL. I may be able to offer more assistance if you offer more details.

Categories

Resources