RESTful degradable JavaScript routing using pushState

Related tags

Routing davis.js
Overview

Davis.js

Description

Davis.js is a small JavaScript library using HTML5 history.pushState that allows simple Sinatra style routing for your JavaScript apps.

Why

Using the history pustState and popstate events allows the links and forms in your app to have hrefs and actions that point to real end points on your server. This allows complex JavaScript apps to degrade gracefully when JavaScript is unavailable and combining this with a template system that can be used both client and server side allows for large amounts of code reuse.

Davis.js is heavily inspired by Sammy.js (hence the name), it is however intentionally much lighter than Sammy.js because I never use any of the template rendering etc that it includes. All Davis.js does is provide a simple routing layer, nothing more, nothing less.

Requirements

Davis.js requires jQuery 1.4.2+ as well as a modern browser that supports HTML5 history.pushState and the onpopstate event. At the moment that means FireFox 4+, Safari 5+, Chrome, iOS Safari 4+*, Android Browser 2.2+, Opera 11.50+.

In all other browsers Davis.js is currently unsupported, all links and forms will have their default behaviour. You can bind to the 'unsupported' event on an app to handle this situation in your code. Fallback to location.hash and onhashchange is a possibility in the future.

*Whilst pushState is supported in iOS it has several, fairly serious bugs. Davis will not fire the unsupported event though as technically iOS does support davis.

Installation

Download davis.min.js and include it on your page after jquery.

Example

A very simple example of a Davis.js app:

var app = Davis(function () {
  this.get('/welcome/:name', function (req) {
    $('body').append('<h1>Hello there, ' + req.params['name'] + '!</h1>')
  })
})

$(document).ready(function () {
  // append a link to trigger the route
  $('body').append('<a href="/welcome/bob">Greet</a>');
  
  app.start();
})

We create a new instance of a Davis.App using the Davis.js function, passing in a function that will draw the routes for the application. Inside this function this is the instance of our application.

We define a simple get route with a 'name' parameter and a callback that will append a message to the html body. Inside the route callback this is set to the request that matches the route, this request is also passed as a parameter to the callback.

Once the app is configure it needs to be started. You start a Davis.js app by calling the start method, this must be done once the document is ready. Now if you click on the link that we appended to the body our route should be called and a friendly greeting printed on the page.

To use Davis your html file must be loaded from a server rather than just opening the file in your browser.

More

API docs

Example using davis.js and a mustache templates shared between the client and the server, code

Contributing

Contributions are more than welcome, to make the process easier and quicker please follow these guidelines:

  • Open an issue detailing the bug fix or feature in your patch.
  • Add test cases for your code.
  • Don't change the version or build new versions as part of you patch.

Running examples

First you'll need node installed for the server. Then execute the following command and visit one of the examples: http://localhost:3000/examples/todo.html.

$ make test

Feedback

Any feedback or suggestions are welcome via issues.

Comments
  • Routing Paths with Query Strings

    Routing Paths with Query Strings

    Routes that contain query strings are dysfunctional. I've fixed this in my branch, but as I'm quite inexperienced with the codebase I have no idea if my fix is fool-proof. In addition to ?, I allowed . character in the route pattern.

    opened by hleinone 21
  • Chrome 21 back button

    Chrome 21 back button

    I'm just looking into a bug where if I go from a davis.js enabled page, to a normal page it correctly does a full page load, then hit back, the url changes and popstate is fired, but nothing happens. The 'normal' page does not have davis.js included, so I find it odd that it's trying to use it. Any ideas?

    opened by iainxt 11
  • listener: Allow user to open new tabs by holding Ctrl while clicking a link

    listener: Allow user to open new tabs by holding Ctrl while clicking a link

    Capturing all clicks regardless of modifier keys breaks basic expected browser behavior, specifically allowing a new tab to be opened. Middle button mouse button still works as expected. This patch causes the davis listener to ignore ctrl+clicks on links, thereby restoring expected behavior.

    Note: I am not sure if that's the correct modifier key for Mac OS. I'd appreciate if somebody with access to a Mac could verify that.

    opened by manuel-woelker 11
  • Discover routing when page rendered.

    Discover routing when page rendered.

    I was checking out Davis, and it looks like a really neat API. Thanks!

    One thing I liked about Backbone Routing is that when a user visits http://localhost/foo/bar (or http://localhost/#/foo/bar) it will automatically discover which route it belongs to. Server side, we just render that page to the (index /) and then the JavaScript routes would call the correct listener.

    Is Davis going to do something like that in the near future? The reason why I am asking, I am only using server side for RESTful / or WebSocket API, all the App runs client side, the server just spits out just the HTML5 and serves the basic JavaScript entry file. When a user visits a certain page directly, I just populate the models from the server into a JSON in the template so the models in client side will pick it up dynamically from page load.

    Thanks!

    opened by mohamedmansour 10
  • Are request.params supposed to be encoded?

    Are request.params supposed to be encoded?

    It appears the parameters in request.params are already encoded. This is not what I was expecting. Is this correct behavior?

    That is if I post with a request parameter /[email protected]

    request.param['email'] == stuff%40crap.com 
    

    I expect:

    request.param['email'] == [email protected]
    
    opened by agentgt 8
  • Wild card patterns for paths

    Wild card patterns for paths

    From what I gather is no wild card path support right? In other words you can't do something like the following:.

        var app = Davis(function () {
          this.get('/welcome/**', function (req) {
            alert("Hello " + req.params['name'])
          })
        })
    

    "**" in this case means all paths and subpaths underneath '/wecome/' an example implementation in Java is here: http://static.springsource.org/spring-security/site/docs/3.1.x/apidocs/org/springframework/security/web/util/AntPathRequestMatcher.html

    opened by agentgt 7
  • Doesnt work if bookmarked

    Doesnt work if bookmarked

    I loved this plugin due to all features. but why does it call only default route when i use a bookmarked link. it works only and only with a tags like #something , is that a bug or you didnt add that feature. its crucial

    opened by asifashraf 7
  • Bad handling of links w/ query strings without routes

    Bad handling of links w/ query strings without routes

    This affects the latest version, 0.9.1.

    A simple page showing this issue can be found here: http://goo.gl/42KGV

    If I have a link with no matching route, usually it works well ... until I found that this doesn't work when the link has a query string attached.

    a href="/blah.html?foo=bar"

    will cause Davis to direct the browser to "/blah.html%3Ffoo=bar?foo=bar" instead of "/blah.html?foo=bar".

    opened by agildehaus 6
  • Really fixing the popstate hasPopped() stuff

    Really fixing the popstate hasPopped() stuff

    Maybe something changed in a recent version of chrome, but it seems this isn't working 100%.

    These two situations have the exact same sequence of events as observed by the current Davis.history code, both on 64-bit Gentoo Linux:

    1. This situation is in Firefox 10.0.4: -Load a page by typing in a URL (so there is no state associated) -Click a link to a route -Refresh the page -Click the back button

    2. This situation is in Chrome 19.0.1084.52 -Load a page by typing in a URL (so there is no state associated) -Refresh the page

    In both of these situations, onpopstate is fired, window.history.state == null and event.state == null, and they are both the first onpopstate received. It seems like the if statement at https://github.com/olivernn/davis.js/blob/master/lib/davis.history.js#L35 once may have helped differentiate this case, but it can't any more.

    Was window.history.state once undefined in chrome?

    The symptom of this is that in chrome, the route is fired twice on page refresh or initial load. I don't see an easy way to fix this without checking to see webkit or non-webkit. Any ideas?

    opened by mschulkind 6
  • Manually trigger or parse a route

    Manually trigger or parse a route

    Let's say I have an app with some get routes defined.

    In some cases I need to manually trigger one of these routes by passing a path as string. I don't know which route it might belong to, so I need Davis to act as if a link has been clicked. I know there is state and trans methods available, but it doesn't cover my need.

    How can I trigger/parse from within an app object or from outside that object?

    opened by ali-sattari 5
  • Route is triggered when location.hash is changed.

    Route is triggered when location.hash is changed.

    I am using location.hash to keep track of where in a list a user is on the page.

    The issue I am having is when I update location.hash it triggers the same route again.

    Is this expected behavior? If so, is there a way to keep the route from being triggered if location.hash changes?

    opened by chrishoage 5
  • License Text

    License Text

    Hi,

    Would it be possible to provide an official license file for davis.js? I see in the source it uses the MIT License, however the text needs to be completed with a year and author name.

    https://en.wikipedia.org/wiki/MIT_License#License_terms

    Thanks, Rob

    opened by ArktekniK 0
  • Davis Router is not working FirefoxOS

    Davis Router is not working FirefoxOS

    In Firefox OS, We can use JS/HTML/CSS for app development.

    Only difference is, it work with app:// protocol instead of http:// protocol

    So, when I click on a <a href="/register"></a> then things are not working,

    In normal browser setup,

    Line number 1759 in Davis Router

       var route = self.lookupRoute(request.method, request.path);
    

    here, request.path is equal to /register

    But when I run the same code in FirefoxOS then

    request.path is equal to app://3d97ccba-ab8c-4a3f-937f-fc894260b23c/register

    So, Its a bug. I am digging more into it.

    opened by nsisodiya 1
  • routeCollection is empty

    routeCollection is empty

    If routes are defined after the app has been instantiated, the routeCollection[] is empty, and as such forPageLoad request throws an error

    To reproduce:

    var router = Davis(function() {
      this.settings = {
        linkSelector: scope + ' a',
        formSelector: scope + ' form',
        generateRequestOnPageLoad: true,
        throwErrors: true,
        handleRouteNotFound: false,
      };
    });
    
    router.get('/post/:id', function());
    router.start();
    
    opened by hypeJunction 0
Owner
Oliver Nightingale
Oliver Nightingale
a tiny and isomorphic URL router for JavaScript

Synopsis Director is a router. Routing is the process of determining what code to run when a URL is requested. Motivation A routing library that works

a decoupled application framework 5.6k Dec 28, 2022
JavaScript Routes

Introduction Crossroads.js is a routing library inspired by URL Route/Dispatch utilities present on frameworks like Rails, Pyramid, Django, CakePHP, C

Miller Medeiros 1.4k Oct 22, 2022
pjax is a jQuery plugin that uses ajax and pushState to deliver a fast browsing experience with real permalinks, page titles, and a working back button.

pjax = pushState + ajax pjax is a jQuery plugin that uses ajax and pushState to deliver a fast browsing experience with real permalinks, page titles,

Chris Wanstrath 16.8k Jan 5, 2023
History.js gracefully supports the HTML5 History/State APIs (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState

History.js gracefully supports the HTML5 History/State APIs (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState. Supports jQuery, MooTools and Prototype.

Browser State 10.8k Dec 26, 2022
A boilerplate for building production-ready RESTful APIs using Node.js, Express, and Mongoose

By running a single command, you will get a production-ready Node.js app installed and fully configured on your machine. The app comes with many built-in features, such as authentication using JWT, request validation, unit and integration tests, continuous integration, docker support, API documentation, pagination, etc. For more details, check the features list below.

Hagop Jamkojian 5k Dec 31, 2022
RESTful API using Hapi NodeJs Framework. This app is project from Dicoding Couses, Belajar Membuat Aplikasi Back-end untuk Pemula

RESTful API using Hapi NodeJs Framework. This app is project from Dicoding Couses, Belajar Membuat Aplikasi Back-end untuk Pemula

Muhammad Ferdian Iqbal 1 Jan 3, 2022
🎵 simple and RESTful API for getting lyrics of any song made using Next.js and ChakraUI.

playground . guide . discord Overview Lyrist is a simple yet powerful RESTful API for getting lyrics of any song using song name and it's artist name.

ashish 21 Dec 17, 2022
It shows how to escape cross-origin issues for web client and API server using CloudFront routing.

AWS CloudFront의 URL Routing을 이용한 Web Client 및 API Server 구현 여기서는 CliendFront의 URL Routing을 이용하여 Web Client와 API Server를 구현하고자 합니다. Web Client는 Amazon

John Park 4 Nov 20, 2022
RESTful HTTP client for JavaScript powered web applications

Amygdala is a RESTful HTTP library for JavaScript powered web applications. Simply configure it once with your API schema, and easily do GET, POST, PU

Lincoln Loop 392 Dec 6, 2022
🚀 A RESTful API generator for Node.js

A RESTful API generator rest-hapi is a hapi plugin that generates RESTful API endpoints based on mongoose schemas. It provides a powerful combination

Justin Headley 1.2k Dec 31, 2022
A jQuery plugin for easy consumption of RESTful APIs

jQuery REST Client v1.0.1 Summary A jQuery plugin for easy consumption of RESTful APIs Downloads Development Version Production Version File Size Repo

Jaime Pillora 618 Nov 20, 2022
Framework for setting up RESTful JSON APIs with NodeJS.

Restberry works with both Express and Restify! Framework for setting up RESTful JSON APIs with NodeJS. Define your models and setup CRUD API calls wit

Restberry 117 Jul 5, 2021
Lolis-rest - RESTful API for lolis-api

Lolis REST RESTful + Website for Lolis API. Introduction This is a RESTful API which will be used on Lolis API Website and Wrapper. This API uses Imgu

Waifu.sbs 3 Aug 11, 2022
A Node.js Express backend for a Stackoverflow like answering forum, with RESTful endpoints

A Node.js Express backend for a Stackoverflow like answering forum, with RESTful endpoints, written in es6 style with linted and comprehensively unit-tested code. Utilizes a local json database using fs but has full separation of concern to implement anything else.

Dhiman Seal 3 Jan 9, 2022
MiniSense RESTful API

MiniSense RESTful API Why was it developed This project is part of an activity proposed by SenseUp aimed at approving a selection process for a Back-E

Alef Sena 1 Jan 21, 2022
RESTful service to provide API linting as-a-service

API Linting Service Prerequisites / general idea General idea behind this API implementation is to provide an API as a service based on the awesome sp

Schwarz IT 6 Mar 14, 2022
Node Express Template (NET.ts) - a small template project which help you to speed up the process of building RESTful API

Node Express Template (NET.ts) - a small template project which help you to speed up the process of building RESTful API

Przemek Nowicki 26 Jan 4, 2023
A dockerized uptime monitoring RESTful API server that allows authenticated users to monitor URLs

A dockerized uptime monitoring RESTful API server that allows authenticated users to monitor URLs, and get detailed uptime reports about their availability, average response time, and total uptime/downtime.

Anas Hamed 2 Oct 7, 2022
A focused RESTful server framework for Deno 🌰🦕

acorn Rapidly develop and iterate on RESTful APIs using a strongly typed router designed for Deno CLI and Deno Deploy. import { Router } from "https:/

oak 24 Dec 10, 2022