Given:
Tom — who has a modern browser which is pushState-enabled
Fred — who has a browser which is not pushState-enabled
a super.app web application powered by Backbone
Tom browses to products/1 page where a #special-offer section exists.
Does Backbone allow Tom to share a link with Fred including the anchor to the special-offer section: http://super.app/products/1#special-offer
Will Fred be redirected to http://super.app/#products/1 (eg: without the #special-offer)?
In other words, does Backbone allow to use anchors?
I had a test here http://bl.ocks.org/abernier/raw/3183257/
It appears that YES:
anchors can be used with pushState-enabled browsers : http://bl.ocks.org/abernier/raw/3183257/product1.html#special-offer
while for IE<10, it is converted to http://bl.ocks.org/abernier/raw/3183257/#product1.html eg: without #special-offer
The only thing I had to take care about was to disable anchors for hashes-based history browsers, by:
if (!Backbone.history._hasPushState) {
$('body').delegate('a[href^=#]', 'click', function (e) {
e.preventDefault();
});
}
Backbone has a very customizable use of hash URL fragments within its modules Router and History.
Related
Assuming I am currently on the page:
www.mysite.com/root/#/?page=orderpage
On the page, I have a link:
Click Here for Mobile
I want to make it such that when the user clicks on the "Click Here For Mobile" link, I can take the user to:
www.mysite.com/root/mobile/#/?page=orderpage
Notice that the URL is similar to what it was before (preserving whatever parameters were there), except there is a "mobile" in between the root and the #.
How do I make it such that the "Click Here For Mobile" link will have the redirect to the appropriate URL as described above?
Is it good practice to do this? Examples appreciated.
As Ajay said, client-side routing will not be possible in this case.
So what you're left with is either doing (like Ajay said):
<a target="_self" href="/root/mobile/#/?page=orderpage">
Or, you could define a function (in a service, in the specified controller, or someplace else where you have access to it) that takes a string and changes the $window.location.href (this will result in a page reload).
Something like this:
app.controller("SomeCtrl", function ($scope, $location, $window) {
$scope.changeUrl = function (url) {
var newUrl = $location.$$absUrl.replace("/#/", url);
$window.location.href = newUrl;
};
});
And then in your html you would use:
Go mobile
Without Javascript enabled (which I'm assuming you're not gonna be supporting with an Angular app) this would not take you anywhere. In that case, Ajay's solution is definately the prefered one.
The benefit of turning it into a function is that all you have to pass is what you're changing before the "/#/".
Good luck :)
I have a site that has a user page. On that page, there are several links that let you explore the user's profile. I'd like to make it so that, when one of those links is clicked on, the url changes, but the top third of the page containing the user's banner doesn't reload.
I'm using Backbone.js
I have a feeling that I'm in one of those situation where I have such a poor understanding of the problem I'm dealing with that I'm asking the wrong question, so please let me know if that appears to be the case
My mistake was assuming that there was a special, built-in way of doing this in backbone. There isn't.
Simply running the following line of code
window.history.pushState('object or string', 'Title', '/new-url');
will cause your browser's URL to change without reloading the page. You can open up the javascript console in your browser right now and try it with this page. This article explains how it works in more detail (as noted in this SO post).
Now I've just bound the following event to the document object (I'm running a single page site):
bindEvents: () ->
$(document).on('click', 'a', #pushstateClick)
pushstateClick: (e) ->
href = e.target.href || $(e.target).parents('a')[0].href
if MyApp.isOutsideLink(href) == false
if e.metaKey
#don't do anything if the user is holding down ctrl or cmd;
#let the link open up in a new tab
else
e.preventDefault()
window.history.pushState('', '', href);
Backbone.history.checkUrl()
See this post for more info.
Note that you CAN pass the option pushstate: true to your call to Backbone.history.start(), but this merely makes it so that navigating directly to a certain page (e.g. example.com/exampleuser/followers) will trigger a backbone route rather than simply leading to nowhere.
Routers are your friend in this situation. Basically, create a router that has several different routes. Your routes will call different views. These views will just affect the portions of the page that you define. I'm not sure if this video will help, but it may give you some idea of how routers interact with the page: http://www.youtube.com/watch?v=T4iPnh-qago
Here's a rudimentary example:
myapp.Router = Backbone.Router.extend({
routes: {
'link1': 'dosomething1',
'link2': 'dosomething2',
'link3': 'dosomething3'
},
dosomething1: function() {
new myapp.MyView();
},
dosomething2: function() {
new myapp.MyView2();
},
dosomething3: function() {
new myapp.MyView3();
}
});
Then your url will look like this: www.mydomain.com/#link1.
Also, because <a href=''></a> tags will automatically call a page refresh, make sure you are calling .preventDefault(); on them if you don't want the page to refresh.
let's say that I have two "pages" (endpoints) on a chaplin.js site
the routes:
match('', 'first_controller#show');
match('second_view', 'second_controller#show');
and two links:
Go to home
Go to Second
the generated urls are "correct":
mysite.com/something/ (home)
mysite.com/something/second_view (second view)
(notice that I'm not on the root of the site). When I start the application at "home" and then click the "Go to second" link i get correctly redirected to the second view, everything gets tendered correctly and the url on the browser changes to mysite.com/something/second_view
But then I cannot refresh the navigator since my webserver will try to reach a second_view folder instead, and I'll get a 404.
What i need is to always generate the urls using a # like in backbone, something like mysite.com/something/#/second_view.
BTW: that last link works but chaplin deletes the # (like a redirect)
Maybe I need to configure something? or change something on the ùrl`helper, I couldn't find anything in the docs. Any Ideas??
Thxs
Backbone itself allows this functionality out of the box, through
Backbone.history.start({pushState: false})
(the default)
You can see the startHistory call here.
You just have to pass this options object as a second parameter to initRouter in your Application :
this.initRouter(routes, {pushState: false});
Can I disable these fellas? I am using angular.js in asp.net mvc app, and I don't need angular to control anything related to address bar or the links...
Right now in html5 mode disabled ($locationProvider.html5Mode(false)) it adds hash and action method's name to the address-bar, for example: you go to \Home\index, it navigates and then address bar text changes into Home\index#\index. ain't that's annoying?
if I enable html5 mode it stops loading pages at all (except the initial). I try going from initialy loaded page to another - it changes the address-bar's text (without adding hashtag thing this time) but won't load the page itself. ain't that frustrating?
A makeshift solution exists here AngularJS 1.1.5 - automatically adding hash tag to URLs
The answer explains the first step (as explained above, with the addition of the new hash-prefix)
yourApp.config(['$locationProvider', function($locationProvider){
$locationProvider.html5Mode(true).hashPrefix('!');
}]);
The first bit handles Angular interfering with your address-bar visually, but now clicking on any links doesn't function properly as (read: history.pushState)
So, the workaround, as pointed out by user #Kevin Beal is some variation of setting the target of the <a> to _self
$('a[href]').attr({'target':'_self'})
or on a case-by-case basis:
Foo
Bar
Although, for the sake of convenience and sanity, I think it's combination of these.
Markup sans target
Foo
Bar
JS
// If `http` protocol present, assume external link
$('a[href^="http://"]').attr({'target':'_blank'});
// Otherwise, assume internal link
$('a:not([href^="http://"])').attr({'target':'_self'});
Worth noting that the above selectors do required jQuery proper.
Is there any feature to retrive some content from the Cakephp controller side and to send it to a File which then opens a Print dialog box to send it to a Printer in Cakephp or JQuery?
Firstly, you might want to consider using a print stylesheet. This will allow you to hide certain things from your layout when users print your pages such as the navigation, the search box, the footer, etc.
A List Apart: Articles: CSS Design: Going to Print
Print Stylesheets - css-discuss
Secondly, you can use jQuery to unobtrusively insert a javascript "Print this page" link which will popup the browser's "Print" dialog on the user's screen when activated.
Unobtrusive JavaScript Print Link (with jQuery) | Trevor Davis
Progressive enhancement with jQuery » MakeMineATriple
Since this is a client side thing, there is no real CakePHP solution for the problem. The only thing you can do is disable or change the layout used with the following in your controller:
$this->layout = false;
$this->layout = 'print';