BackboneJs Browser refresh should load the same page - javascript

I'm new to backboneJs.
Currently when i do browser refresh, it takes back me to login page.
var AppRouter = Backbone.Router.extend({
routes : {
// Pages
'startup' : 'LoginScreen',
'Home' : 'HomeScreen',
'AssetDetail':'AssetScreen',
'*actions' : 'LoginScreen'
},
...
});
var initialize = function(options) {
var appView = options.appView;
var router = new AppRouter(options);
router.on('route:LoginScreen', function(actions) {
require([ 'login/LoginView' ], function(StartView) {
console.log(" --route login");
var startView = new StartView();
});
});
router.on('route:HomeScreen', function(actions) {
require([ 'home/HomeView' ], function(HomeScreenView) {
console.log(" --route home");
var homeScreenView = new HomeScreenView();
});
});
router.on('route:AssetDetailScreen', function(actions) {
require([ 'views/AssetDetailView' ], function(AssetDetailScreenView) {
var assetdetailScreenView = new AssetDetailScreenView();
});
});
Backbone.history.start({pushState: true});
};
So lets say my current url is http://localhost:8080/myapp/# , and when i do browser refresh (F5 may be) , I want to load the same page.
How do I do it ?, Help me!

Not me who originally wrote this answer but I think it's the best solution.
*"You can call Backbone.history.loadUrl.
To refresh the current page:
*`Backbone.history.loadUrl(Backbone.history.fragment);`*
Or as a link handler:
// Backbone.history.navigate is sufficient for all Routers and will trigger the
// correct events. The Router's internal navigate method calls this anyways.
var ret = Backbone.history.navigate(href, true);
// Typically Backbone's history/router will do nothing when trying to load the same URL.
// But since we want it to re-fire the same route, we can detect
// when Backbone.history.navigate did nothing, and force the route.
if (ret === undefined) {
Backbone.history.loadUrl(href);
}"*
Backbone: Refresh the same route path for twice

Related

Opening links in phonegap's inAppBrowser

i'm having difficulties trying to open up links in phonegap's (cordova's) inAppBrowser.
I need to be able to make it so the IAB can open both local phonegap links (file:///android_assets/www/example.html) and online links (https://www.google.com for instance)
I have achieved this so far by creating an object in index.js which creates an initiate IAB object, and then for every call from there onwards I was thinking that I could just open that link.
I've found a number of problems, for example when I try to use window.location = some_url it will change the index.html page to that some_url and hence my attached JS no longer works.
I've tried injecting a window.location from my index.html's JS into the IAB document however that breaks down when trying to fetch a local file
My current method is causing a memory leak because it's continuously opening IAB objects which I'm then having difficulties closing because ...
Using the .close() method on an IAB object shows (according to Chrome's Remote Devices view) that it doesn't actually delete the IAB window but rather turns it into an about:new tab
Heres my current code for the JS which is called in index.js (im sorry i know there's a lot of redundant code!)
var interceptor = {
// library dictionary object of <K,V> pairs in the form of <current page, desired page>
// insert your k,v pairs here:
library: {
'login/signup.php': 'example.html', //test data
'calendar/view.php': 'example.html',
'course/view.php?id=10': 'example.html'
},
// origin dictionary
// dictionary for redirecting from the phonegap page to the moodle page
// must be explicit in your page names and avoid duplication
// e.g. use full path notation -> full/path/to/file.html not file.html
origin: {
'current/attempt': ['example1.html', 'example2.html', 'course/index.php'] //test data
},
history_stack: [],
// stack of all current windows
browser_windows: [],
is_back: 'false',
windows: 0,
redirect_flag: false,
first: true,
currentWindow: null,
currentLocalFile: null,
get_origin: function() {
return this.origin;
},
get_library: function() {
return this.library;
},
// interceptor constructor
initialize: function(old_ref = null, default_url = config.moodleURL, android = true) {
// interval for checking our back flag
// the scope changes when you enter the anonymous closure and this changes. this is a hack for that
var self = this;
var ref;
console.log('default url: ' + default_url);
// check for android
if ((android) && (self.windows < 1)) {
// self.browser_windows[0] = cordova.InAppBrowser.open(default_url, '_blank', 'location=no,zoom=no');
ref = cordova.InAppBrowser.open(default_url, '_blank', 'location=yes,zoom=no');
self.first = false;
}
// otherwise iOS
else if ((!android) && (self.windows < 1)) {
// self.browser_windows[0] = cordova.InAppBrowser.open(default_url, '_blank', 'location=no,zoom=no,suppressesIncrementalRendering');
ref = cordova.InAppBrowser.open(default_url, '_blank', 'location=no,zoom=no,suppressesIncrementalRendering');
// self.browser_windows.push(ref);
self.first = false;
} else {
old_ref =
// old_ref = cordova.InAppBrowser.open(default_url, '_blank', 'location=yes,zoom=no');
ref = old_ref;
}
self.windows++;
var library_dictionary = this.get_library();
var origin_dictionary = this.get_origin();
var redirect_URL;
ref.addEventListener('loadstart', function(event) {
// push current page to histoy stack
self.history_stack.push(event.url);
// check to see if an element of one of our origin arrays is in the URL
for (var origin_list in origin_dictionary) {
if (event.url.includes(origin_list)) self.redirect_flag = true;
for (var elements in origin_dictionary[origin_list]) {
// if it is raise a flag and store the key that its array maps to
if ((event.url.includes(origin_dictionary[origin_list][elements])) && (self.redirect_flag)) {
redirect_URL = origin_list;
self.redirect_flag = false;
var temp_previous_pages = self.history_stack;
var temp_element;
// pop elements of stack until empty
while (temp_previous_pages.length !== 0) {
temp_element = temp_previous_pages.pop();
// if we find an element in the stack (our URL history) that matches the key that our array mapped to
if (temp_element.indexOf(redirect_URL) !== -1) {
// redirect and break from loop
self.initialize(ref, temp_element, android);
break;
}
}
}
}
}
for (var key in library_dictionary) {
if (event.url.includes(key)) {
self.initialize(ref, library_dictionary[key], android);
break;
}
}
});
ref.addEventListener('loadstop', function() {
// when we've finished loading our page set up an interval every 2.5 seconds to check
// if we've been signalled to change pages
console.log('here');
var is_back_interval = setInterval(function() {
ref.executeScript({
code: "localStorage.getItem('is_back')"
}, function(values) {
if (values[0] === 'true') {
// if we have been signalled then remove that signal from our html or moodle page
ref.executeScript({
code: "localStorage.setItem('is_back', '')"
});
// get 3rd last since the last will be the current page as will the 2nd last
prev_page = self.history_stack[self.history_stack.length - 3];
self.initialize(ref, prev_page, android);
}
});
}, 2500);
});
}
};
and heres index.js
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
if (window.device.platform === "iOS"){
interceptor.initialize(config.moodleURL, false);
} else {
interceptor.initialize();
}
}
};
example.html: https://gist.github.com/anonymous/28a78ab0879878d7a9dac8eb89544cda

pushState in backbone.js

I'm trying to get pushState to work in my backbone app. It works fine when just clicking the link. But if i refresh a page i get 404.
Router
Router = Backbone.Router.extend({
routes: {
'home': 'home'
},
home: function() {
new HomeView({el:'#main-view'})
}
});
When a-tag gets clicked:
event.preventDefault();
App.navigate(event.target.pathname, { trigger: true });
start history:
Backbone.history.start({pushState:true});
and html:
<li>
home
</li>
Whats wrong here?
The problem is you use a real HTML link, so it refreshes the page, it's the normal behaviour.
But you would like to change only the current route, not to reload the page.
For that, you can handle the links to say to Backbone : "handle my links !".
Here is an example of the JS that I use to handle links that have "innerlink" CSS class as a route.
'use strict';
var Backbone = require('backbone');
var $ = require('jquery');
Backbone.$ = $;
module.exports = function() {
// Use absolute URLs to navigate to anything not in your Router.
var openLinkInTab = false;
// Only need this for pushState enabled browsers
if (Backbone.history._hasPushState) {
// console.log('YES you have push state !');
$(document).keydown(function(event) {
if (event.ctrlKey || event.keyCode === 91) {
openLinkInTab = true;
}
});
$(document).keyup(function() {
openLinkInTab = false;
});
// Use delegation to avoid initial DOM selection and allow all matching elements to bubble
$(document).on('click', 'a.innerlink', function(evt) {
// Get the anchor href and protcol
var href = $(this).attr('href');
var protocol = this.protocol + '//';
console.log('backbone_pushstate_router:', href, protocol);
evt.preventDefault();
// Ensure the protocol is not part of URL, meaning its relative.
// Stop the event bubbling to ensure the link will not cause a page refresh.
if (!openLinkInTab && href.slice(protocol.length) !== protocol) {
evt.preventDefault();
// Note by using Backbone.history.navigate, router events will not be
// triggered. If this is a problem, change this to navigate on your
// router.
Backbone.history.navigate(href, true);
}
});
} else {
console.warn('no push state');
}
};
Enjoy :)

Multiple routes not working correctly in backbone.js

I'm trying to create a basic webapp that displays images when a specific URL is reached. In this case, I'm using backbone.js's hash system.
I'm trying to make it so that when "www.website.com/index.html#1" is reached, the first image is displayed using some JavaScript that I have. I also need it so that if "www.website.com/index.html#1/#3/#5" is reached, the first, third, and fifth image is displayed. I know that I have to use multiple routes to do this, but I'm not sure how.
I have one working route for the first image that works awesomely. I just don't know how to adapt it so that it works with multiple routes.
Here's the working hash -
<script>
$(function(){
var hideOne = function () {
//alert("hideOne");
var elem = document.getElementById("one");
elem.className = "hide";
};
var Workspace = Backbone.Router.extend({
routes: {
"test":"test",// #test
},
test: hideOne
});
var router = new Workspace();
Backbone.history.start();
});
</script>
It's awesome, it works, it doesn't even refresh the page. But when I try to add another route to that, it all fails. Like, if I added a "test1":"test1" under the "test":"test", the original "test":"test" won't work anymore(neither will the new one, of course).
I've even tried copying+pasting that entire block of code and trying to make a whole new route block of code. That doesn't work either. I'm really stumped here.
Any suggestions would be awesome.
Thanks
You should limit the scope of your first use case. Don't depend on external functions for now. Do something like
routes: {
"test":function(){
alert("test");
},
"test2":function(){
alert("test2");
}
},
Then change to
routes: {
"test":"test",
"test2":"test2"
},
{
test: function(){
alert("test");
},
test2: function(){
alert("test2");
}
}
Read more: http://mrbool.com/backbone-js-router/28001#ixzz3ANyS0hkR
Once you have that working, then start working on DOM manipulation.
routes: {
"?*:queryString": 'showImages'
},
showImages: function(queryString) {
console.log(queryString); // #1#3#5
}
You can use the route "?*:queryString" to match this URL "www.website.com/index.html#?#1#3#5".
The functions "showImages" will be called and passing the value #1#3#5 in the queryString param.
So from other questions posted on StackOverflow, and some that I posted myself, some great users have helped me out and I've solved it.
Here's the code that I have to use -
<script>
$(function(){
var hideMany = function () {
var toHide = [].slice.call(arguments);
toHide.forEach(function (id) {
if(id === null) { return }
var elem = document.getElementById(id);
if(elem) {
elem.className = "hide";
}
});
};
var Workspace = Backbone.Router.extend({
routes: {
"hide(/:a)(/:b)(/:c)" : "test"
},
test: hideMany
});
var router = new Workspace();
Backbone.history.start();
});
</script>
So when you type "www.website.com/index.html#hide/ID1/ID2/ID3", it'll hide the elements with the IDs that you typed in.
I don't fully understand it, but I'm working on breaking it down and figuring out how it works. Thanks for all the help, guys!

Detect path name changes in ember.js

I have some functionality that i need to change whenever the path changes. Often you would solve that problem with the following.
myProp: ( ->
# .. Do something here
).property('currentPath')
The problem with currentPath, is that it only detect route changes, so the following transition is not detected.
/blog/my-awesome-blog-post -> /blog/new-awesome-post
Because they are working on the same route, but i need to detect when a transition like that happens, as i need to update my social media sharing links.
I have tried something like the following with no luck.
App = Ember.Application.create({
conf: config,
currentPathName: '',
});
App.initializer({
name: 'Path name observer',
initialize: function(container, application) {
var router = container.lookup('router:main');
router.addObserver('url', function() {
var lastUrl = undefined;
return function() {
Ember.run.next(function() {
var url = router.get('url');
if (url !== lastUrl) {
App.set('currentPathName', url);
lastUrl = url;
}
});
};
}());
}
});
And then observe 'App.currentPathName', but this somehow messes the router up, as the url's suddenly doesn't change on click.
Any suggestions?
This is the solution i got from a friendly soul # github. This is not currently documented, but works quiet nicely.
Ember.Router.reopen({
doSomethingOnUrlChange: function() {
console.log(this.get('url'));
}.on('didTransition')
});

Using Backbone.js to handle browser history

I'm trying to use Backbone.js to handle the browser history. I'm not setting up Views / Models because I don't want it to handle this, and probably because of this I'm not getting it to work properly.
At this point my page is changing urls. Like:
domain.com/services
domain.com/products
domain.com/contact
domain.com/gallery
domain.com/gallery/photo1
The problem is: if I try to reload the page at domain.com/gallery/photo1. I get the error Uncaught SyntaxError: Unexpected token <
All other pages with just one level permalink works properly on reload. Am I missing something on Backbone?
I'm just using Backbone.Router and Backbone.history.
Is there any simple tutorial on how to set up a site with backbone.js? Just the history thing?
Here's my script:
var Router;
var myRouter;
$(document).ready(function(){
Router = Backbone.Router.extend({
initialize : function(options) {
//
},
routes: {
'' : 'home',
'*actions' : 'pages'
},
home : function() {
this.render('/');
},
pages : function(actions) {
this.render(actions);
},
render : function(path) {
var fullLine = '';
path = (path === '/' || path === '')? '/' : path;
console.log('path: ' + path);
}
});
myRouter = new Router();
Backbone.emulateHTTP = true;
Backbone.emulateJSON = true;
Backbone.history.start({pushState: true, root: "/backbone_teste/"});
// MENU CLICK
$('.menu').children('li').each(function(){
$(this).click(function(){
myRouter.navigate($(this).attr('data-id'), true, true);
});
});
});
Thanks for your help!
Problem Solved:
I just added to my index.php file the following code at the head section:
<base href="http://localhost/backbone_teste/" />
And it works.
Anyway I would like to know why this happens and why Backbone.js documentation don't mention this.
I found the solution at this link: HTML5 History / pushState URLs, .htaccess and You
Thanks

Categories