How can I build routing into a SPA jQuery app? - javascript

I am building a simple MVP of an idea in jQuery and Rails 5. I would like to avoid introducing a front end framework for the purposes of the simple project.
In order to let users navigate with the forward/back button I made different templates with "routes" such as /profile and /network as follows.
I use popstate to change which handlebars template I render (in the onPopState function):
window.addEventListener('popstate', onPopState, true);
I use pushState when I navigate to a new page (I navigate just by swapping which handlebars template and event handlers I am showing):
history.pushState({page: 'home'}, 'Page Title | Home', app.client + '/home');
I have most of the functionality working. The only problem is that if I refresh the page or type in a URL like myapp.com/profile in the address bar directly I get logged out and/or see an error, either a 404 if the app is deployed, or a Cannot GET /profile if I am running on localhost.
I think the issue is that I need to implement some kind of routing on the front end, but I am not sure how / which to use. Are there simple ways to implement this with just jQuery / JavaScript?
Thanks!

Related

AMP - how to make a link to back previous page in amp?

I am using blade template of laravel.
Do we have any way to implement back function in amp page?
I tried 3 ways but all are fail:
a on="tap:AMP.goBack" does not work
a href="javascript:history.back()" will work but it get error from validator amp.
amp-script does not support History API.
Amp dev advise me to use: AMP.goBack(navigate=true). Now it works same as javascript:history.back().
Refs:
https://github.com/ampproject/amphtml/pull/26585
https://github.com/ampproject/amphtml/issues/5225

Change page without reloading header/footer?

I've seen a lot of sites recently that allow you to navigate to different pages (seemingly) without reloading the page. For example:
https://www.protest.eu/shop/category/men/
I know I can do it via AJAX by just replacing the content and changing the url, but that has drawbacks. Mainly, if you're trying to track page visits, they won't show up for pages that are navigated to in this way... because you're not actually visiting the page.
Is there a better way to achieve this?
I know I can do it via AJAX
That's how you do it.
if you're trying to track page visits, they won't show up for pages that are navigated to in this way
How you fix that depends on what you are using to track page visits.
If, for example, you were using Google Analytics then you would do something like:
function ajaxLoadHandler() {
var content = this.responseText;
var url = "/bar.html";
update_content_with(content);
history.pushState({ raw_content: content }, "page 2", url);
ga('send', {
hitType: 'pageview',
page: url
});
}
This approach is called as SPA (single page application). The dowbacks you mentioned earlier can handled by some Js methods and event listener(histrory.pushstate, onpopstate... ref:https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate.)
Some of JS framework s (like React,Backbone,CanJS,SpineJS,BatmanJS,EmberJS,AngularJS, etc) help to achive SPA sloution. These framework provides routing module to achive browser history functionality also these provides view, model, controller, collection WTC.,. You may choose one of these framework which suits for your business need.

backbone routes and pushstate

In my backbone application I trying to tidy my URLs up a little bit, I am wanting something that looks like this,
http://develpoment.dev/dashboard
htttp://development.dev/project/create
What is happening at the moment is that if I navigate too, http://develpoment.dev/#dashboard then the hash gets stripped out and the page loads as I would expect it too.
However if I directly access http://develpoment.dev/dashboard then I get a 404 page not found, this it not great for users who want to bookmark or return an URL later, have I set something up incorrectly?
Here is how I initialize my Router.
$(function(){
App.Routes.Application = new App.Routes.app();
Backbone.history.start({ pushState: true });
});
404 is expected result as you dont have any page under http://develpoment.dev/dashboard URL
In case of single page application, all URLs under site domain should be mapped to one page, the bootstrap page you start application with.

AngularJS history manipulation

Normally with JavaScript you can use the following to manipulate the history, but it does not work.
Example: What I want to achieve is to go to /clients/:id and then when I go back, I want to go to /blog/, doesn't matter which page i was on before.
$scope.changeView = function(clientId){
history.pushState({}, null, '/#/blog');
$location.path('/client/' + clientId);
};
However, this does not work in Angular.
Any idea how this could be solved?
As I am confused about what your question is.. (Are you just trying to find an Angular way of manipulating the history? Or are you trying to redirect?)
Something that may be of interest to you is the $location service on AngularJS.
I just used history.pushState(), null, '/aboutus') while on a page within my app, clicked a link, then went back and it seemed to load that '/aboutus' link just fine, so long as your Angular app is configured to route that path somewhere.

Angular routing without changing location

Chrome Packaged Apps have a rather strict Content Security Policy. One result of this is that manipulating the location (like clicking on a link) results in:
'Can't open same-window link to "chrome-extension://lkjasdfjklbdskjasdfjkhfdshjksad/derp.html"; try target="_blank". '
Target _blank will open the link in chrome which is not what I want. Can AngularJS' routing work in such a locked-down environment?
They docs give an example of an Angular app, but conspicuously does not use routing.
Update
Here is the link that, when clicked, gives the error: <a class='walrus-link' ng-href='paystubs/{{walrus.id}}'>Walrus {{id}}!</a>
Instead of using an href, try using ng-click and call a method to your controller the relocates to the appropriate page using $location. See the documentation on the AngularJS site. The following quote from the doc gives an indication that the $location service might be appropriate for you:
When should I use $location? Any time your application needs to react
to a change in the current URL or if you want to change the current
URL in the browser.
Your code might look something like this:
<a class='walrus-link' ng-click='getPaystub(walrus.id)'>Walrus {{id}}!</a>
and in your parent controller, you'll need a scope method called 'getPaystub' with a line similar to:
$scope.getPaystub = function(selectedWalrusId) {
$location.path('paystubs/'+$scope.walrus.id);
}
This way angular keeps control and won't cause a page refresh. This hopefully keeps you within the bounds of the CSP. Unfortunately I cannot test this in a packaged app, but I've used the exact same convention in a web app and it works just dandy.
routing works for me in my chrome app when not using $routeProvider's html5 mode (which is disabled by default), you just have to use a hash in the url.
so my links look like this:
About
$routeProvider configuration is as follows:
$routeProvider.when('/about', {templateUrl:'about.html'})

Categories

Resources