1
0
Fork 0
mirror of https://github.com/kbparagua/paloma synced 2023-03-27 23:21:17 -04:00
page-specific javascript for Rails done right
Find a file
2016-03-25 13:23:15 +08:00
app/views/paloma minor refactor 2016-03-02 11:36:51 +08:00
lib Tests for multiple js calls 2015-08-28 15:13:28 +08:00
test_app do not put request data on params 2016-03-25 13:23:15 +08:00
vendor/assets/javascripts/paloma do not put request data on params 2016-03-25 13:23:15 +08:00
.gitignore fix .gitignore 2015-04-25 16:55:21 +08:00
Changelog.md 4.2.1 2015-09-01 16:04:18 +08:00
DEVELOPMENT.md Update DEVELOPMENT.md 2015-04-25 16:51:53 +08:00
Gemfile Test commit with new git user 2012-12-21 14:29:09 +08:00
License Create License 2012-12-19 02:41:52 -08:00
paloma.gemspec Do not start Paloma's engine if current request and last request are the same 2016-03-02 12:01:19 +08:00
README.md Update README.md 2016-03-07 13:36:59 +08:00
TODO.md Update old markdowns 2013-10-12 22:14:12 +08:00

Important

  • master branch contains the bleeding edge development code.
  • check branches or tags for the latest stable release or specific versions.

Paloma

Page-specific javascript for Rails done right.

Advantages

  • Choose what specific javascript code to run per page.
  • Easily make ruby variables available on your javascript files.
  • Can be written using vanilla javascript, coffeescript, and anything that compiles to js.
  • No external library dependency.
  • Easy to understand (because it is patterned after Rails' controller module).

Quick Example

Paloma controller.

Paloma.controller('Users', {
  new: function(){
    // Executes when Rails User#new is executed.
    alert('Hello Sexy User!');
  }
});

The Rails controller app/controllers/users_controller.rb:

def UsersController < ApplicationController
    def new
      # nothing special
      @user = User.new
    end
end

That's it! Simply Sexy!

Minimum Requirements

  • Rails 3.1 or higher

Install

  1. Install gem.
  • Without bundler: sudo gem install paloma.
  • With bundler, add this to your Gemfile: gem 'paloma'
  1. Require paloma in your application.js: //= require paloma

  2. In your layouts insert Paloma's hook.

    application.html.erb

    <html>
       <head>
       </head>
    
       <body>
          <%= yield %>
          <%= insert_paloma_hook %>
       </body>
    </html>
    
  3. Start Paloma. Most of the time this will be inside document.ready.

$(document).ready(function(){
  // Execute Paloma's callback.
  Paloma.start();
});

Controllers

Controllers are classes that handle requests made by Rails Controllers. Each Rails Controller's action will be mapped to a specific Paloma Controller's action.

Creating a Controller

A Controller constructor is created or accessed (if it already exists), using Paloma.controller() method.

var ArticlesController = Paloma.controller('Articles');

It will return the constructor function of your controller.

Note: Using Paloma.controller method, you can access the same controller constructor across different files.

Handling Actions

Every time a request to Paloma is made (A Rails Controller action is executed), an instance of a Paloma controller is created and the method responsible for the request will be invoked.

Add actions directly to the constructor's prototype.

var Articles = Paloma.controller('Articles');

Articles.prototype.edit = function(){
  // Handle edit article
};

Or pass the prototype value directly as the 2nd argument of the controller method.

Paloma.controller('Articles', {
  edit: function(){
    // Handle edit article
  }
});

Namespace

Namespaced controller should follow this format: namespace/controller.

Rails controller:

class Admin::UsersController < ApplicationController
  def new
    @user = User.new
  end
end

Paloma controller:

Paloma.controller('Admin/Users', {
  new: function(){
    // Handle new admin user
  }
});

Controller Inheritance

It is also possible to create a controller that is a subclass of an existing controller, using the following syntax: Controller < ParentController

Paloma.controller('Application', {
  index: function(){
    alert('Application: Index');
  },
  
  new: function(){
    alert('Application: New');
  }
});

Paloma.controller('Users < Application', {
  // Override Application's new action
  new: function(){
    alert('Users: New');
  }
});

Advanced Usage

You can manipulate what controller/action should Paloma execute by calling js method before rendering.

  1. Changing controller

    class UsersController < ApplicationController
       def new
          @user = User.new
          js 'Accounts' # will use Accounts controller instead of Users controller
       end
    end
    
  2. Changing action

    You can use the symbol syntax:

    def new
       @user = User.new
       js :register # will execute register method instead of new
    end
    

    Or the string syntax:

    def new
       @user = User.new
       js '#register'
    end
    
  3. Changing controller and action.

    def new
      @user = User.new
      js 'Accounts#register' # will execute Accounts#register instead of Users#new
    end
    
  4. Changing controller with namespace.

    Paloma supports namespaces using '/' as delimiter.

    def new
       @user = User.new
       js `Admin/Accounts` # will use Admin/Accounts controller instead of Users controller
    end
    
    def new
       @user = User.new
       js 'Admin/Accounts#register' # will execute Admin/Accounts#register instead of Users#new
    end
    

Passing Parameters

You can pass parameters to your Paloma Controller in two ways.

  1. Passing a hash. (parameters only)
def show
  user = User.find params[:id]
     
  js :id => user.id
end
  1. Passing path and a hash.
def show
  user = User.find params[:id]
  
  js 'Admin/Users', :id => user.id
end

Using both ways, you can access the passed params using the params property of your Paloma controller.

Paloma.controller('Users', {
  show: function(){
    alert("User id: " + this.params.id);
  }
});

Preventing Paloma Execution

If you want to Paloma not to execute in a specific Rails Controller action you need to pass false as the Paloma parameter.

def edit
  @user = User.find params[:id]
  js false
end

Controller-wide setup

You can call js outside Rails controller actions for global or controller-wide settings.

Example:

class UsersController < ApplicationController
   js 'Accounts' # use Accounts controller instead of Users for all actions.


   def new
      @user = User.new
   end
   
   def show
      @user = User.find params[:id]
   end
end

Like before_filter you can also pass only and except options.

class UsersController < ApplicationController

   js 'Admin/Accounts', :except => :destroy # Use Admin/Accounts except for destroy method

end

IMPORTANT NOTE: If you are going to pass parameters for Controller-wide settings, put them inside a :params hash.

class UsersController < ApplicationController
  js 'Accounts', :params => {:x => 1, :y => 2, :z => 3}, :only => :show
end

Overriding Controller-wide setup

If you want to override the controller-wide setup, just call js again inside a controller action. From there you can override the controller/action or pass additional parameters.

class UsersController < ApplicationController

   js 'Accounts', :params => {:x => 1}
   
   
   def new
      @user = User.new
      js :register, :y => 2 # will execute Accounts#register with params {:x => 1, :y => 2}
   end
end

Hook

insert_paloma_hook is a helper method that you can use in your views to insert Paloma's HTML hook. Inside this HTML hook is where the magic happens. This is the reason why Paloma can magically know what Javascript controller/action to execute. To further understand how Paloma works, you can inspect the HTML hook, by checking the generated HTML (inspect element) and locate the div element that has the class js-paloma-hook.

Ideally, you just need to call insert_paloma_hook in your layouts, since the layout will always be included in every rendered view. But if you are rendering a view without a layout, make sure to call insert_paloma_hook in that view.

AJAX

  1. Make sure that the AJAX response contains the html hook. (use insert_paloma_hook)

  2. Start Paloma on complete/success.

    $.get('http://example.com', function(response){
       $('#result').html(response);
       Paloma.start();
    });
    

Execute Paloma when user hits Back or Forward button.

Paloma executes page-specific javascript by adding a <script> tag to the response body. Turbolinks, by default, executes any inline javascript in the response body when you visit a page, so the <script> tag appended by Paloma will automatically be executed. However, when Turbolinks restores a page from cache (this happens when a user hits Back or Forward button in his browser) any inline javascript will not be executed anymore. This is the intentional behavior of Turbolinks, and it is not a bug. If you want to execute Paloma again when Turbolinks restores a page, do something like this:

$(document).on('page:restore', function(){
  Paloma.start();
});

Gotchas

  • Make sure that the rendered view has the paloma hook (use insert_paloma_hook) for Paloma to execute.

Where to put code?

Again, Paloma is now flexible and doesn't force developers to follow specific directory structure. You have the freedom to create controllers anywhere in your application.

Personally, I prefer having a javascript file for each controller.

Contribute

  1. Fork.
  2. Do awesome things.
  3. Submit Pull-Request to master branch.
  4. Add short summary of changes on your PR.