jcontroller 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +153 -18
- data/app/assets/javascripts/jcontroller.js +6 -10
- data/jcontroller.gemspec +1 -1
- data/lib/jcontroller/filter.rb +1 -1
- data/lib/jcontroller/version.rb +1 -1
- data/lib/jcontroller.rb +3 -0
- data/spec/fake_app/app/controllers.rb +6 -1
- data/spec/fake_app/app/views/users/parameters_template_params.js.jbuilder +1 -1
- data/spec/fake_app/routes.rb +1 -0
- data/spec/features/jcontroller_spec.rb +14 -3
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dc0dec2d86a61f9e4f6d4a0c1522ad298ba5252
|
4
|
+
data.tar.gz: feda08b748ad215642d79e191635e4f92b4c6cb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44b2653eba12e626f017460ae7287f2e1e3340cd07b631763e43cd99730c6689bb1951b510fa7e422796d07d3456f64642b030cec80c9a06de23a11a019781c9
|
7
|
+
data.tar.gz: ee1bce67790d5a99b7cfae9870daf6985f85885635b810e9f0a493c68115df10cb337fa055946aac14539d532dc16b175ad86964d96fb772ecc83ff1241843da
|
data/README.md
CHANGED
@@ -1,29 +1,164 @@
|
|
1
|
-
# Jcontroller
|
1
|
+
# Jcontroller [![Gem Version](https://badge.fury.io/rb/jcontroller.png)](http://badge.fury.io/rb/jcontroller) [![Build Status](https://travis-ci.org/s12chung/jcontroller.png?branch=master)](https://travis-ci.org/s12chung/jcontroller?branch=master) [![Code Climate](https://codeclimate.com/github/s12chung/jcontroller.png)](https://codeclimate.com/github/s12chung/jcontroller)
|
2
|
+
Rails controller based javascript to keep your javascript outside of your views.
|
2
3
|
|
3
|
-
|
4
|
+
Based off [Paul Irish's DOM-based Routing](http://www.paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/)
|
5
|
+
(or Garber-Irish Implementation). __Works with turbolinks__
|
4
6
|
|
5
|
-
##
|
6
|
-
|
7
|
-
|
7
|
+
## How it works
|
8
|
+
```javascript
|
9
|
+
Jcontroller.create('users', {
|
10
|
+
html: {
|
11
|
+
// executes whenever users#index with html format is executed
|
12
|
+
index: function() {}
|
13
|
+
}
|
14
|
+
});
|
15
|
+
```
|
16
|
+
No other code is needed.
|
8
17
|
|
9
|
-
|
18
|
+
## Installation
|
19
|
+
Add `gem 'dom_routes'` to your application's `Gemfile` and run the `bundle` command, then add this to your `app/assets/javascripts/application.js`
|
10
20
|
|
11
|
-
|
21
|
+
//= require dom_routes
|
22
|
+
|
23
|
+
## Controllers
|
24
|
+
### Namespaces
|
25
|
+
Jcontroller creation and finding are based off the controller path.
|
26
|
+
```javascript
|
27
|
+
// for Admin::UsersController
|
28
|
+
Jcontroller.create('admin/users', {});
|
29
|
+
```
|
30
|
+
### Filters
|
31
|
+
Jcontrollers can be created with before and after filters like so:
|
32
|
+
```javascript
|
33
|
+
Jcontroller.create('users', {
|
34
|
+
html: {
|
35
|
+
// executes for all html format responses for UsersController, before the specific action
|
36
|
+
before: function() {}
|
37
|
+
// executes whenever users#index with html format is executed
|
38
|
+
index: function() {}
|
39
|
+
// executes for all html format responses for UsersController, after the specific action
|
40
|
+
after: function() {}
|
41
|
+
}
|
42
|
+
});
|
43
|
+
```
|
44
|
+
### Inheritance
|
45
|
+
By default, jcontrollers inherit from the `application` jcontroller and will execute it if it exists, such as:
|
46
|
+
```javascript
|
47
|
+
Jcontroller.create('application', {
|
48
|
+
html: {
|
49
|
+
before: function() {}
|
50
|
+
index: function() {}
|
51
|
+
after: function() {}
|
52
|
+
}
|
53
|
+
});
|
54
|
+
```
|
55
|
+
So with the jcontrollers above the order of execution is:
|
56
|
+
- `application.before`
|
57
|
+
- `users.before`
|
58
|
+
- `application.index`
|
59
|
+
- `users.index`
|
60
|
+
- `application.after`
|
61
|
+
- `users.after`
|
12
62
|
|
13
|
-
|
63
|
+
You can also set your own inhertance chain:
|
64
|
+
```javascript
|
65
|
+
Jcontroller.create('users', {
|
66
|
+
parent_path: 'users_base',
|
67
|
+
...
|
68
|
+
});
|
69
|
+
```
|
70
|
+
## Parameters
|
71
|
+
### Access
|
72
|
+
Parameters are accessed from `this.params`:
|
73
|
+
```javascript
|
74
|
+
Jcontroller.create('users', {
|
75
|
+
html: {
|
76
|
+
index: function() {
|
77
|
+
console.log(this.params);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
});
|
81
|
+
```
|
82
|
+
The request state (controller_path, action_name, jcontroller, etc.) are also given in `this.state`.
|
14
83
|
|
15
|
-
|
84
|
+
### Manual
|
85
|
+
Use the `js` method with the `params` option.
|
86
|
+
```ruby
|
87
|
+
class UsersController < ApplicationController
|
88
|
+
def show
|
89
|
+
@user = User.find(params[:id])
|
90
|
+
js { :params => { :id => @user.id } }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
```
|
94
|
+
### From view template
|
95
|
+
You can also create parameters using a JSON DSL (such as [jbuilder](https://github.com/rails/jbuilder/)) by creating a template named `<action_name>_params.js.<DSL suffix>`:
|
96
|
+
```ruby
|
97
|
+
# app/views/users/show_params.js.jbuilder
|
98
|
+
json.id @user.id
|
99
|
+
```
|
16
100
|
|
17
|
-
|
101
|
+
## Controlling javascript execution
|
102
|
+
### Stop
|
103
|
+
Stop all execution of all filters and methods for the action:
|
104
|
+
```ruby
|
105
|
+
class UsersController < ApplicationController
|
106
|
+
def index
|
107
|
+
js false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
### Different jcontroller
|
112
|
+
Execute a different jcontroller:
|
113
|
+
```ruby
|
114
|
+
class UsersController < ApplicationController
|
115
|
+
def index
|
116
|
+
# same as "users#index.html", parameters and options are optional
|
117
|
+
js "users/show.html", { :params => { ... } }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
```
|
18
121
|
|
19
|
-
|
122
|
+
### HTML view
|
123
|
+
Execute all filters and actions related to a action:
|
124
|
+
```erb
|
125
|
+
<!-- same as "users#index.html", parameters and options are optional -->
|
126
|
+
<%= execute_jaction "users/show.html", { :params => { ... } } %>
|
127
|
+
```
|
20
128
|
|
21
|
-
|
129
|
+
### Manually filter in Javascript
|
130
|
+
You can use the given state to stop execution of functions:
|
131
|
+
```javascript
|
132
|
+
Jcontroller.create('application', {
|
133
|
+
html: {
|
134
|
+
before: function() {
|
135
|
+
if (this.state.action_name === 'destroy') { }
|
136
|
+
}
|
137
|
+
}
|
138
|
+
});
|
139
|
+
```
|
140
|
+
### Redirect
|
141
|
+
You can execute all filters and functions of the current action before the redirected action using:
|
142
|
+
```ruby
|
143
|
+
class UsersController < ApplicationController
|
144
|
+
def index
|
145
|
+
js { :redirect => true }
|
146
|
+
redirect_to user_path(User.first)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
```
|
150
|
+
So `users/index.html` will be executed before `users/show.html`.
|
22
151
|
|
23
|
-
##
|
152
|
+
## Ajax
|
153
|
+
You can optionally execute jcontrollers for ajax instead of writing javascript in views by turning it in `config/application.rb`:
|
154
|
+
```ruby
|
155
|
+
Jcontroller.ajax = true
|
156
|
+
```
|
157
|
+
Jcontrollers will automatically execute with parameters given by the template with a JSON DSL:
|
158
|
+
```ruby
|
159
|
+
# app/views/users/show.js.jbuilder
|
160
|
+
json.id @user.id
|
161
|
+
```
|
24
162
|
|
25
|
-
|
26
|
-
|
27
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
-
5. Create new Pull Request
|
163
|
+
## Credits
|
164
|
+
Extracted out of [Placemark](https://www.placemarkhq.com/). Originally called [dom_routes](https://github.com/s12chung/dom_routes). An alternative is [paloma](https://github.com/kbparagua/paloma).
|
@@ -6,9 +6,7 @@ var Jcontroller = {
|
|
6
6
|
$.extend({
|
7
7
|
parent_path: controller_path === this.application_controller_path ? undefined : "application",
|
8
8
|
parent: function() {
|
9
|
-
if (Jcontroller.blank(this.parent_cache)) {
|
10
|
-
this.parent_cache = Jcontroller.find(this.parent_path);
|
11
|
-
}
|
9
|
+
if (Jcontroller.blank(this.parent_cache)) { this.parent_cache = Jcontroller.find(this.parent_path); }
|
12
10
|
return this.parent_cache;
|
13
11
|
},
|
14
12
|
|
@@ -16,7 +14,7 @@ var Jcontroller = {
|
|
16
14
|
var dup = $.extend({}, this, state.jaction);
|
17
15
|
dup.state = state;
|
18
16
|
dup.params = params;
|
19
|
-
if (Jcontroller.present(dup.parent())) dup.parent_cache = dup.parent().dup(state, params);
|
17
|
+
if (Jcontroller.present(dup.parent())) { dup.parent_cache = dup.parent().dup(state, params); }
|
20
18
|
return dup;
|
21
19
|
},
|
22
20
|
|
@@ -36,7 +34,7 @@ var Jcontroller = {
|
|
36
34
|
if (Jcontroller.present(this.parent())) this.parent().execute_pre_order_filter(filter);
|
37
35
|
},
|
38
36
|
execute_filter: function(filter) {
|
39
|
-
if ($.isFunction(filter)) $.proxy(filter, this)();
|
37
|
+
if ($.isFunction(filter)) { $.proxy(filter, this)(); }
|
40
38
|
}
|
41
39
|
},
|
42
40
|
definition
|
@@ -45,9 +43,7 @@ var Jcontroller = {
|
|
45
43
|
},
|
46
44
|
execute_jaction: function(state, params) {
|
47
45
|
var controller = this.find(state.jaction.controller_path);
|
48
|
-
if (this.present(controller)) {
|
49
|
-
controller.dup(state, params).execute_action();
|
50
|
-
}
|
46
|
+
if (this.present(controller)) { controller.dup(state, params).execute_action(); }
|
51
47
|
},
|
52
48
|
|
53
49
|
blank: function(o) { return typeof o === "undefined" || o === null; },
|
@@ -59,14 +55,14 @@ var Jcontroller = {
|
|
59
55
|
get_or_create: function(namespace_string) {
|
60
56
|
var current_namepace = window;
|
61
57
|
$.each(namespace_string.split('/'), function(index, level) {
|
62
|
-
if (Jcontroller.blank(current_namepace[level])) current_namepace[level] = {};
|
58
|
+
if (Jcontroller.blank(current_namepace[level])) { current_namepace[level] = {}; }
|
63
59
|
current_namepace = current_namepace[level];
|
64
60
|
});
|
65
61
|
|
66
62
|
return current_namepace;
|
67
63
|
},
|
68
64
|
find: function(controller_path) {
|
69
|
-
if (this.blank(controller_path)) return undefined;
|
65
|
+
if (this.blank(controller_path)) { return undefined; }
|
70
66
|
var namespace_string = this.controllers_path + controller_path;
|
71
67
|
|
72
68
|
var current_namepace = window;
|
data/jcontroller.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency 'rails', '>=
|
21
|
+
spec.add_dependency 'rails', '>= 4.0'
|
22
22
|
spec.add_dependency 'request_store'
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler"
|
data/lib/jcontroller/filter.rb
CHANGED
data/lib/jcontroller/version.rb
CHANGED
data/lib/jcontroller.rb
CHANGED
@@ -3,14 +3,19 @@ class ApplicationController < ActionController::Base
|
|
3
3
|
end
|
4
4
|
|
5
5
|
class UsersController < ApplicationController
|
6
|
-
DEFAULT_ACTIONS = %w[state no_action manually_execute
|
6
|
+
DEFAULT_ACTIONS = %w[state no_action manually_execute]
|
7
7
|
(%w[index] + DEFAULT_ACTIONS).each do |action|
|
8
8
|
class_eval <<-END
|
9
9
|
def #{action};end
|
10
10
|
END
|
11
11
|
end
|
12
12
|
|
13
|
+
def parameters_template
|
14
|
+
@parameter_string = "parameter template"
|
15
|
+
end
|
16
|
+
|
13
17
|
def stopped
|
18
|
+
Jcontroller.ajax = !params[:ajax_off]
|
14
19
|
js false
|
15
20
|
end
|
16
21
|
def redirect
|
@@ -1 +1 @@
|
|
1
|
-
json.s
|
1
|
+
json.s @parameter_string
|
data/spec/fake_app/routes.rb
CHANGED
@@ -27,6 +27,12 @@ feature 'invoke correct filter', :js => true do
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
def test_no_elements
|
31
|
+
within @test_append_selector do
|
32
|
+
all('div').size.should == 0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
30
36
|
it "should pass the state of the request" do
|
31
37
|
visit state_users_path
|
32
38
|
find(@test_append_selector).text.should == {
|
@@ -68,9 +74,7 @@ feature 'invoke correct filter', :js => true do
|
|
68
74
|
|
69
75
|
scenario "when stopped" do
|
70
76
|
visit stopped_users_path
|
71
|
-
|
72
|
-
all('div').size.should == 0
|
73
|
-
end
|
77
|
+
test_no_elements
|
74
78
|
end
|
75
79
|
scenario "when redirected" do
|
76
80
|
visit redirect_users_path
|
@@ -102,6 +106,13 @@ feature 'invoke correct filter', :js => true do
|
|
102
106
|
end
|
103
107
|
|
104
108
|
context "with ajax" do
|
109
|
+
scenario "ajax off" do
|
110
|
+
visit stopped_users_path(ajax_off: true)
|
111
|
+
click_link "ajax link"
|
112
|
+
wait_for_ajax
|
113
|
+
test_no_elements
|
114
|
+
end
|
115
|
+
|
105
116
|
scenario "basic controller" do
|
106
117
|
visit stopped_users_path
|
107
118
|
click_link "ajax link"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jcontroller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Chung
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: request_store
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|