GithubHelp home page GithubHelp logo

finnsson / pagerjs Goto Github PK

View Code? Open in Web Editor NEW
272.0 27.0 68.0 1.6 MB

The Single Page Application Framework for KnockoutJS

Home Page: http://pagerjs.com/

License: MIT License

JavaScript 34.86% CSS 4.86% ApacheConf 0.04% HTML 60.24%

pagerjs's Introduction

Build Status

Logo

one having or covering a specified number or kind of pages
  - Merriam-Webster

See the demo.

pager.js is a JavaScript library based on KnockoutJS and jQuery that provides the possibility of creating single page applications in a declarative fashion - nesting subpages inside subpages where each subpage can be developed standalone but still communicate between each other.

This makes it easier to design very large scale single page web sites.

This readme is for version 1.1.0

Getting Started

See the demo.

Install

Download

Using npm

npm install pagerjs

Dependencies

You will usually use pager.js in combination with either jQuery hashchange or History.js.

pager.js is not depending on any CSS framework!

For developing pager.js you'll also need

Philosophy

Developing a huge single page application should be like developing multiple small pages. That is the only way you'll be able to scale up and out the development. In order to ease development in the large pager.js got

  • views (pages) that can be loaded on-demand
  • view-models that can be loaded on-demand

These MVVM-triads can be developed in isolation and later on connected.

FAQ

Can I use it together with...

pager.js is not depending on anything but jQuery and KnockoutJS. You can use it together with any CSS framework.

Can I use true URLs instead?

Yes. PagerJS supports true URLs with History.js.

Release Notes

1.1.0

1.0.1

1.0.0

  • A lot of cleanup and some breaking changes!

0.7

0.6

0.4

0.2

Roadmap

See Milestones.

How to Contribute

Fork this repo. Install all dependencies (node.js, grunt, phnatomjs). Run all tests (grunt qunit). Run jslint (grunt lint). Make your changes. Run all tests and the linter again. Send a pull request.

Contributors

finnsson

GilesBradshaw

tedsteen

Shildrak

adimkov

imrefazekas

altmann

huochunpeng

Munter

alvingonzales

CuinnWylie

DKhalil

License

pager.js is under MIT license.

Copyright (c) 2013 Oscar Finnsson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pagerjs's People

Contributors

adimkov avatar alvingonzales avatar cuinnwylie avatar dkhalil avatar fbuchinger avatar finnsson avatar gianpaj avatar gilesb2 avatar hirokiky avatar justlep avatar jzabroski avatar maliberty avatar manzanotti avatar munter avatar nemzes avatar ptolts avatar rocketmonkeys avatar shildrak avatar stormpat avatar tedsteen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pagerjs's Issues

Should be possible to send URI (fragment identifier) parameters to a page

A page should be able to access the information in the current route - changing a view-model.

Sending parts of the fragment identifier to variables in the view-model is possible using
params.

<div data-bind="page: {id: 'search', params: {'name', 'fromdate'}}">
  <span data-bind="text: name"></span> (<span data-bind="text: fromdate"></span>)
</div>

where name and fromdate with be bound by the parameters name and fromdate.

An example route for the example above could look like

example.com/#search/tv?name=samsung&fromdate=20121010

or if HTML5 history is used

example.com/search/tv?name=samsung&fromdate=20121010

Should send wildcards to source

<div data-bind="page: {id: 'start'}">
    <a href="#user/fry">Go to Fry</a>
</div>

<div data-bind="page: {id: 'user'}">
    User:
    <!-- {1} will be replaced with whatever matched the wildcard -->
    <div data-bind="page: {id: '?', sourceOnShow: 'user/{1}.html'}">
    </div>
</div>

Should specify relative page paths using `page-href`

<div data-bind="page: {id: 'start'}">
  <!-- This will update href to #start/bender -->
  <a data-bind="page-href: 'bender'">Bender</a>

  <!-- This will update href to #admin/login -->
  <a data-bind="page-href: '../admin/login'">Admin Login</a>

  <div data-bind="page: {id: 'bender'}">Bender!</div>
</div>
<div data-bind="page: {id: 'admin'}">
  <div data-bind="page: {id: 'login'}">Login</div>
</div>

Based on the total path of the page the binding calculates an absolute href.

delete me?

my mistake completely. works as intended.

Don
have a great day

demo: Lazy Load External Content not working same as Load External Content

In playing with demo page Lazy Load External Content (on a local server since online demo is currently out of sync with repo content (e.g., missing CSS class linenums)), despite having CSS classes prettyprint linenums, line numbers are not shown. If I manually run prettyPrint() in the console it works right. If I add page property callback source: prettyPrint(), it also doesn't work. Using an instrumented callback in source, it looks like refresh of the page triggers calling the callback twice which seems like another bug? Is this a known limitation / working-as-designed / user error?

IE8 Date.now

IE8 throws an error due to Date.now not existing.

Should have

if (!Date.now) {
Date.now = function() {
return new Date().valueOf();
};
}

At the head of pager.js

Access to Page in withOnShow handler

First, thanks for creating a really nice library!

It would be nice to have access to the Page object when dynamically fetching viewmodels in "withOnShow". I modified the source for withOnShow to pass "this", just like you are currently doing for sourceOnShow:
I replaced
572 - }, this));
572 + }, this), this);

This allow me to retrieve specific data for my views based on the route, eg

http://domain.name.com/order/56

 <div data-bind="page: {id: '?', withOnShow: MyNamespace.Order.GetModel()}"></div>

MyNamespace.Order = {
    GetModel: function () {
        return function (callback, page) {
            $.getJSON('/api/orders/' + page.currentId, function (data) {
                var viewModel = new MyNamespace.Order.ViewModel(data);
                callback(viewModel);
            });
        };
    }
};

Off course, ability to use wildcards would be even better, to say something like:

 <div data-bind="page: {id: '?', withOnShow: MyNamespace.Order.GetModel({1})}"></div>

But I don't think this is an easy addition? However, I hope you will consider adding the page parameter as described above.

Uncaught TypeError: Object #<Object> has no method 'start'

Current (0a1f5b0bc15f4731345e88920a64093c63b4a335) pager.js causes
Uncaught TypeError: Object #<Object> has no method 'start' for standard initialization code, while dist/pager.min.js works (this was somewhat difficult to track down). I prefer to use pager without requirejs.

Scoped pure view observables using `vars`

<!-- x and y are now available as observables, but only in the view (not the view-model) -->         
<div data-bind="page: {id: 'foo', vars: ['x','y']}">                                                 
  <span data-bind="text: x"></span>                                                                  
  <span data-bind="text: x"></span>                                                                  
</div>                                                                                               

This is useful for effects that has nothing to do with the view-model.

Should be possible to add guards

Guards are methods that are run before the page navigation takes place and
that can stop the navigation from displaying a certain page.

Use the property guard: someMethod do apply the guard. The method
takes three parameters: page, route and callback. If the callback is called
the navigation takes place - otherwise it is stopped.

<div data-bind="page: {id: 'admin', guard: isLoggedIn}">
  This page is only accessible if the user is logged in.
</div>

where

isLoggedIn: function(page, route, callback) {
    if(viewModel.loggedIn()) {
        callback();
    } else {
        window.location.href = "login";
    }
}

Use cases are login, validating steps in state machines, etc.

The reason the guard takes a callback as third argument is simply because the guard might be async - accessing
a webserver for login details or asking if a valid shopping card exists etc.

Named binding of child elements using `bind-child`

<div data-bind="page: {id: 'foo'}">                                              
  <div>                                                                          
    <span data-bind="page-child: 'name'"/>                                       
    <span data-bind="page-child: 'age'"/>                                        
  </div>                                                                         
</div>                                                                           

Now name and age are available in the Page-instance under the elementChildren-observable, e.g. this.elementChildren().name() and this.elementChildren().age().

Load external content with Wildcard and nested navigation

Firstly, thanks for your job, it's good idea and implementation.

I'm trying to implement following scenario:

in the main page only one "navigation node"

<div data-bind='page: {id: '?', sourceOnShow: '{1}.html'}'><div>

each loaded element have own navigation... for example into modal view.

Problems:

  1. after recent update external sources not loading into main page, but loaded after page refresh. Url is changed, but nothing happens
  2. nested navigation doesn't work. Url is changing, but nothing happens.

Maybe it's wrong way, but looks like it's should work.

thanks.

Should be possible to route to custom widgets (accordions)

It is possible to create custom widgets that jack into the pager-system.
The page-binding (pager.Page-class) is possible to extend at multiple points.

One custom widget (page-accordion-item) is already implemented.

<div data-bind="page: {id: 'employee'}">
    <div data-bind="page-accordion-item: {id: 'zoidberg'}">
        <a href="#employee/zoidberg">Dog</a>
        <div>Zoidberg Information</div>
    </div>
    <div data-bind="page-accordion-item: {id: 'hermes'}">
        <a href="#employee/hermes">Cat</a>
        <div>Hermes Information</div>
    </div>
</div>

Mapping plugin does not work

The knockoutjs mapping plugin and ko.toJS function doesn't work. I was able to figure out that it is trying to convert the property added to the object by pagerjs and eventually causing javascript to run out of memory and throw an error.

Should be possible to do deep navigation

<div id="start" data-bind="page: {id: 'start'}">
    <a href="#user/fry">Go to Fry</a>
</div>

<div id="user" data-bind="page: {id: 'user'}">
    <div id="fry" data-bind="page: {id: 'fry'}">Fry</div>
</div>

Add BeforeNavigate Event handler to allow user to stop transition

An example would be validation.

If validation fails, you do not want the transition to be performed.

It would be nice if the items that are passed to the event include the current page and the page the user is attempting to navigate to.

If this is the navigate to backlog item then please ignore.

Should do deep navigation with wildcards

<div data-bind="page: {id: 'start'}">
      <a href="#user/leela">Go to Leela</a>
</div>

<div data-bind="page: {id: '?'}">
    Misc:
    <div data-bind="page: {id: 'leela'}">
        Leela
    </div>
</div>

`withOnShow` should lazy bind a new view model to the page

<div data-bind="page: {id: 'user', withOnShow: someMethod('someMethod')}"></div>

someMethod must return a function that takes a callback that takes a view model.

E.g.

function requireVM(module) {
  return function(callback) {
    require([module], function(mod) {
      callback(mod.getVM());
    });
  };
}

Tab panel custom widget

<ul class="nav nav-tabs" data-bind="foreach: $page.children">
    <li data-bind="css: {active: isVisible}"><a data-bind="text: $data.getValue().title, page-href: getId()"></a></li>
</ul>

<div data-bind="page: {id: 'Slagsmålsklubben', title: 'Slagsmålsklubben', sourceOnShow: 'https://embed.spotify.com/?uri=spotify:album:66KBDVJnA6c0DjHeSZYaHb', frame: 'iframe'}" class="hero-unit">
    <iframe width="300" height="380" frameborder="0" allowtransparency="true"></iframe>
</div>

<div data-bind="page: {id: 'Binärpilot', title: 'Binärpilot', sourceOnShow: 'https://embed.spotify.com/?uri=spotify:album:67LKycg4jAoC06kZgjvbNd', frame: 'iframe'}" class="hero-unit">
    <iframe width="300" height="380" frameborder="0" allowtransparency="true"></iframe>
</div>

Demo as is does not work in IE7

Is it just me or does the demo not work in IE7? I can go to different hashes, but the content on the page is not reflected.

Should be possible to load view content using a custom method

In order to facilitate programming in the large it is useful to be able to extract views as separate components.
These views should not be forced to be stored as html-fragments or be loaded with jQuery.

Thus a way to inject custom views should be possible. This is done using the source- or
sourceOnShow-properties. Just supply a method instead of a string!

These properties takes a method that should take a pager.Page as first argument, a callback, and return nothing.

<div data-bind="page: {id: 'zoidberg', sourceOnShow: requireView('character/zoidberg')}" />

where

window.requireView = function(viewModule) {
  return function(page, callback) {
    require([viewModule], function(viewString) {
      $(page.element).html(viewString);
      callback();
    });
  };
};

if

// file: character/zoidberg.js
define(function() {
  return '<h1>Zoidberg</h1>';
});

Should be possible to load content into iframes

<!-- An iframe will be created inside the div -->
<div data-bind="page: {id: 'user', frame: 'iframe', source: 'user.html'}"></div>

<!-- The iframe specified will be used -->
<div data-bind="page: {id: 'fry', frame: 'iframe', source: 'fry.html'}">
    <iframe sandbox=""></iframe>
</div>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.