page-specific javascript for Rails done right
Go to file
kbparauga 297ffb1e5e fix .gitignore 2015-04-25 16:55:21 +08:00
app/views/paloma Fix js(false) issue 2015-03-24 21:40:53 +08:00
lib only include hook if partial is available. Removes conflict with jbuilder and also resolves bug #37 2014-08-19 15:24:55 +02:00
test_app fix .gitignore 2015-04-25 16:55:21 +08:00
vendor/assets/javascripts/paloma Fix js(false) issue 2015-03-24 21:40:53 +08:00
.gitignore fix .gitignore 2015-04-25 16:55:21 +08:00
Changelog.md 4.1.2 release 2015-03-24 22:14:17 +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
README.md Update README.md 2015-04-24 23:21:13 +08:00
TODO.md Update old markdowns 2013-10-12 22:14:12 +08:00
paloma.gemspec 4.1.2 release 2015-03-24 22:14:17 +08:00

README.md

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.
  • Easy to understand (because it is patterned after Rails' controller module).

Quick Example

Paloma controller.

var UsersController = Paloma.controller('Users');

// Executes when Rails User#new is executed.
UsersController.prototype.new = function(){
   alert('Hello Sexy User!' );
};

The Rails controller app/controllers/users_controller.rb:

def UsersController < ApplicationController
    def new
      # a Paloma request will automatically be created.
      @user = User.new
    end
end

That's it! Simply Sexy!

Minimum Requirements

  • jQuery 1.7 or higher
  • Rails 3.1 or higher

Install

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

Controllers

Controllers are just 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.

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

ArticlesController.prototype.new = function(){
  // Handle new articles
};

ArticlesController.prototype.edit = function(){
  // Handle edit articles
};

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 access the parameters on your Paloma Controller using this.params object.

  1. Parameters only.

    users_controller.rb

    def destroy
        user = User.find params[:id]
        user.destroy
    
        js :id => user.id
    end
    

    Paloma controller.

    var UsersController = Paloma.controller('Users');
    
    UsersController.prototype.destroy = function(){
      alert('User ' + this.params['id'] + ' is deleted.');
    };
    
  2. Path with parameters.

    def destroy
       user = User.find params[:id]
       user.destroy
    
       js 'Accounts#delete', :id => user.id
    end
    

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

As of version 4.1.0, Paloma is compatible with Turbolinks without additional setup.

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(){
  // Manually evaluates the appended script tag.
  Paloma.executeHook();
});

You need to manually run Paloma every page load if you are not using jquery.turbolinks gem.

In your application.js

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

Gotchas

  • Paloma will execute on all render calls, except for calls with the following formats: js, json, xml, and file.

    Example:

    render :json => {:x => 1}  # Paloma will not execute`
    render :partial => '/path/to/partial'  # Paloma will execute
    
  • It will cause conflicts if you have a controller and a module that has the same name.

    Example:

    var AdminController = Paloma.controller('Admin');
    
    // This will override the AdminController and replace it
    // with a module named 'Admin'.
    var UsersController = Paloma.controller('Admin/Users');
    

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.