Page specific Javascript for Ruby On Rails application use Webpack to manage assets
MIT License
Page specific Javascript for Ruby On Rails application use Webpack to manage assets.
// npm
npm install --save raicon
// yarn
yarn add raicon
Raicon runs your JS code after DOM is ready (support turbolinks), don't need to add $(document).ready
or document.addEventListener('turbolinks:load', () => {})
.
Define helper method in helpers/application_helper.rb
:
// With *.erb
def raicon_data_attributes
"data-raicon-controller=#{controller_path} " \
"data-raicon-action=#{action_name}"
end
// With *.slim
def raicon_data_attributes
{
data: {
'raicon-controller': controller_path,
'raicon-action': action_name
}
}
end
Add data attributes defined from raicon_data_attributes
method to body
tag:
// With *.erb
<body <%= raicon_data_attributes %>>
<%= yield %>
</body>
// With *.slim
body *raicon_data_attributes
== yield
To run JS on a certain page, you can register a handler like this:
import Raicon from 'raicon';
Raicon.register(targetController, hanlerClass, hasTurbolinks = true);
// Arguments:
// - targetController: string - camelcase transformation of `controller_path` value of the controller from rails.
// - hanlerClass: class - class includes methods (method's name is camelcase transformation of `action_name` value of the controller from rails) to run JS code for specific page.
// - hasTurbolinks: boolean (default is true) - check if we use turbolinks or not
Controller path and action name camelcase transformation example:
// Controller path transformation
controller: 'app/controllers/my_posts_controller.rb' -> controller_path: 'my_posts' -> targetController: 'myPosts'
controller: 'app/controllers/my_admin/my_posts_controller.rb' -> controller_path: 'my_admin/my_posts' -> targetController: 'myAdmin/myPosts'
// Action name transformation
action: 'posts' -> methodName: 'posts'
action: 'favorite_posts' -> methodName: 'favoritePosts'
Example:
Rails controller in app/controllers/my_posts_controller.rb
:
class MyPostsController < ApplicationController
def index; end
def favorite_posts; end
def new; end
def create; end
def edit; end
def update; end
def destroy; end
end
JS Raicon controller:
import Raicon from 'raicon';
class MyPostsController {
beforeEach() {
console.log('Run after DOM ready in all pages');
}
index() {
console.log('Run after DOM ready in page rendered by app/views/my_posts/index.html.erb');
}
favoritePosts() {
console.log('Run after DOM ready in page rendered by app/views/my_posts/favorite_posts.html.erb');
}
new() {
console.log('Run after DOM ready in page rendered by app/views/my_posts/new.html.erb');
this.initForm();
}
edit() {
console.log('Run after DOM ready in page rendered by app/views/my_posts/edit.html.erb');
this.initForm();
}
initForm() {
console.log('Init form');
}
}
Raicon.register('myPosts', MyPostsController);
Reuse method from handler class:
window.myPostsRc = Raicon.register('myPosts', MyPostsController);
// Reuse method in handler
const myPostsController = window.myPostsRc.getHandler();
myPostsController.initForm();
Raicon support :before
and :after
events for every action in controller. The name of event follow this pattern:
'raicon:before:${targetController}#${methodName}'
'raicon:after:${targetController}#${methodName}'
For above raicon controller we have these event listeners:
document.addEventListener('raicon:before:myPosts#index', () => {});
document.addEventListener('raicon:after:myPosts#index', () => {});
document.addEventListener('raicon:before:myPosts#favoritePosts', () => {});
document.addEventListener('raicon:after:myPosts#favoritePosts', () => {});
document.addEventListener('raicon:before:myPosts#new', () => {});
document.addEventListener('raicon:after:myPosts#new', () => {});
document.addEventListener('raicon:before:myPosts#edit', () => {});
document.addEventListener('raicon:after:myPosts#edit', () => {});
This package is available as open source under the terms of the MIT License.