Organize javascript for every Rails route
Ruby JavaScript
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
app
gemfiles
lib
spec
.gitignore
.travis.yml
Gemfile
LICENSE.txt
README.md
Rakefile
dom_routes.gemspec

README.md

DomRoutes

Auto-magical scaffolding for Paul Irish's DOM-based Routing (or Garber-Irish Implementation) way of organizing your javascript.

Works with turbolinks

Purpose

Javascript is hard to organize and debugging ajax is a mess. This is one method to organizing your javascript neatly by mirroring the controllers and having all the it outside of your HTML views.

How it works

Setup your namespace

DR.routes = {
    all: {
        html: {
            before: function() {
            }
        }
    },
    demos: {
        html: {
            before: function() {
            },
            demo_action: function() {
            }
        }
    }
}

What happens

After, requests to demos#demo_action with format html will call the following functions (if they exist):

  • DR.routes.application.html.before
  • DR.routes.demos.html.before
  • DR.routes.application.html.demo_action
  • DR.routes.demos.html.demo_action
  • DR.routes.demos.html.after
  • DR.routes.application.html.after

js format is also supported, i.e.:

  • DR.routes.application.js.before
  • DR.routes.demos.js.before
  • DR.routes.application.js.demo_action
  • DR.routes.demos.js.demo_action
  • DR.routes.demos.js.after
  • DR.routes.application.js.after

Installation

Add this line to your application's Gemfile:

gem 'dom_routes'

And then execute:

$ bundle

Add this to your app/assets/javascripts/application.js

//= require dom_routes

Make sure your app/views/layouts/application.html.erb (and all your other layouts) looks like this:

<html>
<head>...</head>
<body data-controller="<%= js_route.controller_path %>" data-action="<%= js_route.action %>">
    …
    <%= execute_js_routes %>
</body>
</html>

Basic Use

I like to have a JS file for every route in app/assets/javascripts/routes. Like so:

app/assets/javascripts/routes/demos.js:

(function() {
    var demos = DR.define('demos', {
        html: {
            edit: function(params) {
                alert(params.alert_message);
            }
        },

        js: {
            new: function(params) {
                console.log(params.log_message);
            }
        }
    });
})();

DR.define() extends or creates the namespace DR.routes.demos and returns it. This allows me to access DR.routes.demos through the demos variable. You can also use the traditional hash namespacing shown in the Setup your namespace section.

So if a html request is sent to demos#edit, DR.routes.demos.html.edit is called with the HTML view rendering.

For a js request sent to demos#new, DR.routes.demos.js.new is called and nothing else happens.

Templates and parameters

Optional Parameters are passed from a JSON DSL (such as jbuilder) and is passed as the params object to the function. You can pass any JSON object as a template.

HTML

app/views/demos/edit_params.js.jbuilder:

json.alert_message "ploop"

so

DR.routes.demos.html.edit({ alert_message: "ploop" });

is called automatically.

Javascript

For javascript to work, a template must exist. app/views/demos/new.js.jbuilder:

json.log_message "loggggggggggggg"

so

DR.routes.demos.js.new({ log_message: "loggggggggggggg" });

is called automatically.

Advanced Use

Manually execute a route

Use #execute_js_route(js_route=self.js_route, format=formats.first)

Executing a different route

Sometimes you want to execute a different route too. For that, you can specify it like so:

self.js_route = "demos/edit" # can be "demos#edit", "edit", { controller: "demos", action: "edit" }, or a DomRoutes::Route object

When this is done, the original route and the new route will be executed.

Handling redirects with flash

Other times you may want to use a route after a redirect, use #flash_js_route(js_route=nil) then.

Credits

Extracted out of Placemark. Originally called poke_js.

Contribution

Feel free to fork, post issues or send any pull requests. Thanks.