Fine control of history pushstate in Backbone - javascript

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.

Related

react router 5 browser back button changing state

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.

I want to get an event for an HTML onContextMenu *after* the final selection, not at initial click

If I do
<a href ... oncontextmenu="myFunction(event)">
It gets called when the user right clicks on a link, before the context menu appears. But I want to get an event after a context menu item has been selected. Ideally, only when they have selected "Open link in ...", so having access to what they actually clicked is desirable.
Would prefer a non-JQuery answer, but if needed, JQuery is o.k.
Added: Explanation what I'm trying to do:
When the user directly clicks a link to another (commercial hotel finder) site, I bring up a little alert "If you book a room, please enter XXXX as the Gift Code"). Would also like to put up this alert if they right click and open the link in a new tab etc.,.,
Added#2: Thanks for the prompt and direct answers. See my "answer" below for what I ended up doing. I'll leave this question open in case there are other options.
This is not possible to do in Javascript, but you might be able to achieve what you are looking for by replacing the default context menu with a custom one.
You can't. The primary purpose of the contextmenu event is to allow a page to replace the browser's context menu with a menu of its own rendered as HTML. The contents of the browser's context menu are not specified by any HTML standard, and will vary from browser to browser. Most of the options in the context menu refer to actions outside the scope of the page (e.g, "copy", "view page source", "open link in new window", "save as", etc.), and there is no event fired on the page when they are selected unless the action being performed would normally fire an event. (For instance, selecting "Print" might fire onbeforeprint and onafterprint events.)
The WHATWG HTML5 specification specifies a menu element which can be used to add items to the browser's context menu, but it's currently only supported under Firefox. So that's probably not really an option either.
Just an idea, and I'm not sure exactly what you are trying to do, but I would try calling the function on a set delay, like this:
Right-Click Me, then wait for 3 seconds.
The only downside is that once the alert() is called, the context menu is hidden.
Hope this helps!
What I ended up doing is inserting an intermediate page on my site.
Instead of directly going to the external site, the route (I'm using node & Express) brings up a intermediate page with the explanatory text, a checkbox "Got it, don't show this page again", (in my case, the answer gets stored in localStorage, others might store on the server) and a big green OK button that takes you to the external site.
If the route includes the query "?directXXX=true", (read from localStorage) you skip over the intermediate page and are immediately redirected to the external page.
This way I get a much nicer explanatory page, with an image, etc... (dialogs, even if you use something like alertify, look klunky) and I get to "intercept" all calls to the external site.

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...

Backbone render method called but different view displaying on back button press

I have a backbone.js application, and I'm running into a situation where I need to reload a url. In other words, the user is on a current url, and I need to reload the page. To do so, I'm using the solution from this post: Backbone: Refresh the same route path for twice. So if my route looks like this:
"patrons/new(/)":"newPatron",
then I reload the page by calling
router.newPatron();
This all works great. The problem is when I hit the back button. The url will change and go back through the history, but the view doesn't change. On each back button click, the correct render methods are getting called.
So the url and render methods are corresponding to the backbutton changes, but the view is not changing correctly. It is reloading each time I press the back button though?
Anyone know how to fix this?

pushstate - back button not working

If I use ajax to change specific portions of the page, like a content section, which warrants a new URL (and requires one specifically for favoriting, or refreshing), is there some magic that I am not aware of that allows the user to click the back button and reload the content that was just there?
Or do you have to re-retrieve the data based on stored variables using popstate
Thanks!

Categories

Resources