Skip to content
master
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
app
 
 
 
 
lib
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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.

About

Organize javascript for every Rails route

Resources

License

Packages

No packages published