Skip to content


Subversion checkout URL

You can clone with
Download ZIP


How to link to the index / start page without reloading the page #85

drulia opened this Issue · 11 comments

2 participants


I started to use the pager.js, but I can't figure out how can I link to the index page. If I'm in page with url like and I want to link to the url, how can I do that?

I tried href="#", href="#start", page-href: 'start', but non of them seems to work. the best I can achieve is get the page reloaded to required url.

I know it is probably something simple, but just couldn't find an answer anywhere, because all exmples doesn't use history.js and none of the examples redirects to home page, at least in the demo page.


All the history.js-testing is a bit lacking due to (1) I personally haven't used "true urls" in any real projects and (2) I haven't been able to run qunit/phantomjs automated tests with history.js (argh!). Hopefully this will be rectified soon. All feedback regarding the integration with history.js is welcome.

I understand your use case and is testing things. It seems like pager.js isn't handling it correctly. My initial thought would be that you should be able to write

data-bind="page-href: '/'"

in order to get to the "root", but it doesn't seem to work.

I've fixed the issue as my understand of it is. See the file for possible ways you can solve it now. You can either set

data-bind="page-href: '/'"

or you can bind directly to the root-page-instance using

data-bind="page-href: $__page__"

(which is not as beautiful but good to know about). Also observe the element

<base href="http://localhost:3000/test_html5/should_work_with_history_js/"/>

which lets pager.js know that you consider to be the "root".

Finally it should be noted that calling history.js on your own is always possible (History.pushState(null,null,'my-url')). The routing mechanism listens on history.js-events and will react accordingly.

Hope this solves your issue.


Thanks for reply and fix.
I tested a bit more and it seems to works now if I specify data-bind="page-href: $page" though if I specify page-href: '/' it takes me to url, notice two slashes at the end. I tried with wildcards and without.

Also if I understand correctly this page: {id: '?', nameParam: theID} suppose to either bind to theID if observable exists or create it for me, yes? I'm asking because if I'm not creating theID explicitly in the viewModel, it throws me an error ReferenceError: theID id not defined

Also just to clarify, if I have a link in the page to I suppose I have to create link like this data-bind="page-href: '../page1'" and not like this data-bind="page-href: 'page1'", because the latter make url look like

So far if I follow the patterns to create bindings I'm using in urls in the viewModel, create same level links with ../ prefix and for home page links use $page everything works fine on new browsers as well as IE9 which works with hashes.


Would you be interested in making a small example where the double slash-problem is displayed so I can take a look at it? Maybe inside the folder /test_html5/double_slash/ or as a jsfiddle or jsbin-example.

I've also fixed the nameParam-bug and updated the documentation (see!/binding_wildcard_to_observable).


I did this fiddle
Its a very simple one, but it shows the double slash problem. Navigate to to page1, there is a button to go Back, which is linked with $page and works well, then if you navigate to page2, button Back is linked with '/' and if you look at the link in the browser corner while hover the link, you will that provided link contains two slashes at the end.

Anyway, I was playing around a little bit, and did couple simple changes by myself in hp.init, would be very interesting to hear your opinion about changes. There is three changes marked with comment //CODE

All I did is that I added ability to link to the same level url addresses with /page1 instead of ../page1, also the former will take to parent page instead on staying on the same level, the page-href: '/' would take to actual parent page by removing last segment of url, accordingly page-href: '../' would take away two segments from url.

I understand that though small, but these changes would break the current functionality, so I only pasting the code below.

    hp.init = function () {
            var page = this.getParentPage();

            this.path = ko.computed(function () {
                var value = _ko.value(this.pageOrRelativePath()());
                if (typeof(value) === 'string') {
                    var parentsToTrim = 0;
                    // added '/', to support same level links like this '/page'
                    if(value.substring(0, 1) === '/') {
                        value = value.slice(1);
                    } else if(value.substring(0, 3) === '../') {
                        // parentsToTrim is +1, to avoid overlaping of '/' and '../'
                        while (value.substring(0, 3) === '../') {
                            value = value.slice(3);

                    var fullRoute = page.getFullRoute()();
                    var parentPath = fullRoute.slice(0, fullRoute.length - parentsToTrim).join('/');
                    // additional check for value length to prevent URL ending with '/'
                    return (parentPath === '' ? '' : value.length > 0 ? parentPath + '/' : parentPath) + value;
                } else if (value.getFullRoute) {
                    return value.getFullRoute()().join('/');
                return "";
            }, this);

Thanks for the fiddle. I added the code to test_html5/should_not_add_double_slash/index.html as well as some other test cases (nested pages) and now it seems to work.

Regarding the use of ../ I'm afraid you'll have to live with the current solution. To much code is depending on the current interpretation. Think of it as folders and that you are running cd. Hopefully you'll think it makes sense.


Yeah it does make sense. I tried updated version and now it looks like all is working well, I'll let you know if anything will come up.
And thanks for a great router/library!


One question, is it possible and if yes, how could I use isActive if I manually writing the links on the page and not via foreach: $page.children


I guess you want to be able to say "is the page /foo/bar/ active?". In that case you would write something like

<a data-bind="css: {active: $__page__.child('foo')().child('bar')().isVisible}">Some link</a>

or if you want to find a child relative to the page the link is in (if the link is in the page foo):

<a data-bind="css: {active: $page.child('bar')().isVisible}">Some link</a>

but I guess it would look a bit nicer if you first wrote some helper method like (haven't tried the code)

window.getPage = function(key) {
    return ko.computed(function() {
      var keys = key.split('/');
      var lastChild = $__page__;
      for(var i = 0; i < keys.length; i++) {
        lastChild = lastChild.child(keys[i])();
      return lastChild;

that you could use by writing

<a data-bind="css: {active: getPage('foo/bar')().isVisible}">Some link</a>

The method pager.Page.prototype.child will return an observable that either points at the null-object (an empty Page-instance) or the child-page.


That worked well, thanks!
I have been working with pager now, and missed ability to give a starting page any other id but start. I'm not really sure if that was possible, but I was thinking about solution and came up with something like role, so you can set the role explicitly and no matter what the real id is, page will be treated as a start page if you set a role: 'start'. Also this open the doors for a use cases like nested starting pages with their own urls, i.e. if have a page starting with id page1 than inside it I might have something like details1 also with role: 'start', then this page will accessible via any of these urls /, page1, page1/details1, which brings more consistency when you have page1/details2 and page1/details3

I know I used in example a urls with numbers, but that can be anything, in my own website, I have a page starting with url, which is also accesible via or, then inner navigation contains links to and so on and I can use different links for consistency sake.

Although implementation was very simple, I haven't tested yet with anything else but my own use case, so would be very interesting to know what do you think, would that match the concept of the pager.js, maybe there would be possible to implement it in even easier way.

inside function - showChild

var id = child.getId();
var role = child.getRole(); //  asking for role
if (id === currentRoute ||
     ((currentRoute === '' || currentRoute == null) && (id === 'start' || role === 'start')) ) {
     match = true;
     me.currentChild = child;

and this is - getRole

p.getRole = function () {
     return this.val('role') || 'next';

Also I noticed that with isn't working exactly as the normal with does. I tried to prevent rendering the page with with and it just wasn't working, the binding context was changed, but the inner html were rendered even though the binding context was null, which obviously didn't worked well.

The best workaround I can think of would be use of container less bindings inside the page container

<!--ko with: someView()-->
  // my inner content

And now the inner content is not rendered as long as someView returns null, I just implemented the beforeShow function which gives a value for someView() and it allows me to prevent unnecessary loading of the whole page at starting moment, so I can ask for data in server only when that particular page is loaded and overall instantiation happens not on the initial page load moment but on a demand. Somewhat similar to sourceOnShow except that you can control that deep inside your code and load plain JSON from the server.


You solution using roles are interesting. I'll have to look at bit more at your solution when I get home.

You are right that with is not working exactly the same as the normal with. The problem is that KnockoutJS 2.2 got problems with observable view models (which you got) while changing the binding contexts (which pagerjs is doing) at the moment. I've been working on different work-around but none seem to work in all use cases. This will hopefully be adressed in KnockoutJS 2.3 (I cannot find the issue on KnockoutJS issue tracker any longer, but I've seen it).

I should update the docs and point this out as well as post the work around.

@finnsson finnsson closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.