react router 5 browser back button changing state - javascript

In my application, I have a multi-page form that lives on the URL http://localhost:3000/form. When I change pages in the form, the URL remains the same, but the state changes to render different views (pages of the form).
A new feature I want to implement is to allow the browser back button to switch views/pages (aka change state) in the multi-page form.
Is this possible? How can I achieve this?

Why exactly do you want to keep the same route? If a user wants to get back to the same state they were at via a deep link they would not be able to with this implementation would they?
If you want to use the same route you can at least use # routes to keep track of where in the form the user is.
Eg.
http://localhost:3000/form#step1,
http://localhost:3000/form#step2
then the back button would work to move them back a step.

Related

React router 4 - routing questions on architecture using hashes

My Setup
I am using react router 4 in my application and am trying to achieve something along the lines of adding hashes to certain routes on pages, that will save the state of the page so user can link to said state.
So for example - I have products I am listing that have many variants, when the user selects a variant, I add a hash + the variant ID to the URL, so like myapp.com/cars/truck turns to myapp.com/cars/truck#red, this allows users to link to that specific variant, which is what I want.
My problem
My problem arises when the user navigates to a page and selects a few variants, then tries to navigate backward. Because I change the hash, each back step hits the previous variant in the browsers history.
So if
the user lands on home myapp.com/
navigates to myapp.com/cars/truck
then selects the red variant => myapp.com/cars/truck#red,
then blue myapp.com/cars/truck#red => myapp.com/cars/truck#blue
When they press the back button on the browser they will go back to myapp.com/cars/truck#red, when the desired effect is they go back to the previous page omitting the variant and hash changes, which would be myapp.com/.
I understand this is the browsers behavior, but what I am wondering is if there is a way to let users link directly to the variant links, and also have it so pressing the back button after the described scenario takes the user back to the previous page (in that scenario it's myapp.com/). Perhaps re-thinking how I am doing this, I am open to any suggestions.
I am using react (16) and react router (v4) for this if this helps. Happy to show any code if needed, please let me know. Thanks for reading!
Try replaceState, it will update the URL without adding a history entry:
history.replaceState() operates exactly like history.pushState()
except that replaceState() modifies the current history entry instead
of creating a new one. Note that this doesn't prevent the creation of
a new entry in the global browser history.
e.g.
history.replaceState(null, 'Red Truck', '/truck#red')

How to retain page selection on browser back using backbone

In my backbone JS web application, there are two pages i.e. page1 and page2. Page1 has different form controls like radio buttons, check-boxes and drop-downs. I select some controls and navigate to page2. But when I click on browser back button to go to previous page page1 I am loosing all the values in page1. My question is how can I retain the values or information without loosing it. I am looking for backbone JS specific solution.
You could store the data in localstorage or a full fledged database.Define this in your collection, and use the fetch/save methods accordingly.
localStorage: new Backbone.LocalStorage("page1"),
There are plenty of detailed examples on the implementation for localstorage.Here's a link.
Presuming page1 and page2 are routed views and not page loads then when you go back to page1 the render method fires and knows nothing of your previous input values so to capture them you could update the model in page1 with form values as and when they are entered e.g. on change and then render the form with this model instead of a clean or new model. The model should remain in memory when routing to page2 and back to page1.

Add history item to html browser history without changing page angular

I'm attempting to rewrite a small part of user history as soon as they visit my angular application.
Currently I'm attempting to change the last history item to a certain page once the app loads, however instead of just changing the history, the current page/url also changes.
In my app.js where I define my routes for angular I also have a .run containing
history.pushState({}, 'Restaurants List', document.URL.match(/.+#\//).toString() + 'orders/restaurants')
this instantly will change my url from the intended target to the new history entry.
I've also tried using replaceState without any success.
A solution I've thought of is first changing the history then redirecting the user which works fine, but I want to avoid that additional overhead.
Is there any way to just add to the history without going to it so that if the user hits back it goes to a different page?

How to handle pagination in Single Page Application?

On my Single Page Application (Javascript (AngularJs) webapp), I'm displaying a paginated items list.
I'm displaying 10 items per page.
In order to retain the current pagination opened by the user at any time while this one navigates on other page, I put the current page number on browser's localStorage.
Here's an example of workflow:
The user goes to myItemsList.html.
He opens the page 2 involving the url: myItemsList.html?page=2.
Then, he goes to another page: myOtherPage.html.
He goes back to the link initially pointing to myItemsList.html, that displays directly thanks to localStorage the page myItemsList.html?page=2 in order to potentially continue his navigation.
Would it confuse the user, maybe expecting to see the page 1 as a new starting navigation.
If I display at the top of the list, a kind of label like "Page 2" in order to warn him that he's seeing the preceding portion of his navigation, isn't it UX-friendly?
Or should I completely avoid persisting current pagination?
Here's what could happen if I don't persist the current viewed page:
The user goes to myItemsList.html.
He opens the page 2 involving the url: myItemsList.html?page=2
He opens an item in this page (the "show" page), leading to: myItemsList.html?id=123
He clicks on the browser's back button, causing a refresh of myItemsList.html (since a Single Page Application). The current pagination (page 2) would be lost and the user would need to restart it in order to continue its items discovery.
This seems really touchy...
What strategy should I choose for a use case like this?
saving the progress through navigation is the expected behavior in UX design of SPA, so maintaining the page he was in the correct choice, and since it is a pagination it won't be an issue even if the user wants to go back to any page, it will only take a click.
First of all I would avoid using localstorage and use a service instead to persist ur page counter.
Secondly u dont need to persist pg counter to anywhere else but in a scope variable for refreshing to mext page data. You can even think about just adding to results similar to infinitite scroll use cases. But either way, u can use local scope variable for pagination.
Whether to go directly to last viewed page - is a more business decision and will depend on needs.
But u can very easily persist or remove persisted data using broadcast and watch and decide on persistence based on event listened to.
Hope thos helps ...
How about maitaining a sort of heirerachy in JS like this :
Suppose a user navigates to a section called Customer Search
customer_search.customer_display.page = 2
Where customer_search is the a subsection , customer_display is the view with pagination you are targetting .
menu.menu_items.page=7
Where menu is the subsection , menu_items is the view with pagination
Might work if your application is organized in a reasonably hierarchical manner .
Probably you could also maintain the page in $scope for that particular controller .
The URL should dictate the navigation.
When I navigate to your website, e.g. example.com, I expect to be on the first page.
When I navigate to a (bookmarked) page of your website, e.g. example.com?page=2, I expect to be on the second page.
When I hit the back button, I expect to be presented with the previous page exactly as it was when I left it. You don't need to refresh the entire page, just listen to the history events and update accordingly.
And I strongly believe that this question doesn't belong to stackoverflow...

Fine control of history pushstate in Backbone

Sorry, I couldn't think of a good title.
I would like to have the default pushstate behaviour, but have custom behaviour during certain situations.
So I want all links to be normal /login, /register, etc. If the user is on the homepage, I want those links to go to their respective pages through backbone.
However, if the user is one a special page like /product/123, then we are going to show them a modal, and although the href says "/login" I want to simply call the route function to show the login page, append #login to the url (ie "/product/123#login") and add a push state with the hash-tag'd url.
The reasoning behind this, is that someone could be on /product/123, click /login, suddenly decide they want to share the product and have the product url available, then out of habit hit back, to go back to viewing the product [ie. close the login modal], and have it work as expected.
Is the above possible? From what i've been reading, backbone's history module is a set it and forget it kind of thing, and I was unable to see a way through the Backbone documentation.
It's probably not a good idea to have your modal in a route. For most use, a modal window is something that popups on the current page, it's not an actual view change, it's a view that is appended somewhere on top of whatever the user was doing (it's modal in the sense that the user can't continue what he was doing until he handles whatever popped up).
In that regards, the /login route should probably not be a modal but instead a full page view with a login form. Then on your other pages, I assume you have a Layout view that contains a sub-view somewhere that renders the "login modal" button, right? When click on this button, you can handle the modal rendering/appending to body (or however).
In this scenario, there is no need for a URL change, and so, Backbone router won't be involved. My point is that the use case you are describing would only make sense if it was interesting to share a URL (/product/123#login) that would re-open the login modal on the product/123 page (and not on another product)... and I think that's not a very useful feature! In my opinion (and this is very arguable, I am sure), the login modal isn't something that should have a specific route, because it's not an actual stable application path, if that makes sense.

Categories

Resources