Skip to content
euge edited this page Sep 13, 2010 · 1 revision

Controllers in my Javascript?

Sure, why not? Object-oriented design doesn’t have to end with Rails on the server. behaveJS provides the ability to create Javascript controller classes that are analogous to controllers in Rails. Now when Rails renders a controller action, behaveJS will similarly create an instance of the corresponding Javascript controller and invoke the same action. This allows for a very clean way to construct and configure any UI component without littering your views with Javascript.

Example:

Your Rails “profiles” controller has an “edit” action that allows users to upload photos. Your photo upload widget allows for callback functions to be provided for handling upload successes and failures.

You could place all of the configuration for this photo upload widget in your view template, but why make a mess of it? With behaveJS you can keep your views clean and keep the Javascript where it belongs…in a separate file.

behaveJS.createController("Profiles",
{
  initialize : function($super)
  {
    // this controller is inherited from the Application controller, so we call 
    // the parent constructor
    $super();
  },
  edit : function()
  {
    // called when rendering the "edit" action of the "profiles" controller
    this.uploadWidget = new PhotoUploader($("photos"));
    this.onSuccess    = this.onUploadSuccess.bind(this);
    this.onFailure    = this.onUploadFailure.bind(this);
  },
  onUploadFailure : function()
  {
    alert("Sorry your upload failed! Please try again.");
  },
  onUploadSuccess : function()
  {
    alert("Thanks for your photo!");
  }
});

behaveJS will create the controller and call the appropriate action on Prototype’s “dom:loaded” event, ensuring that you can access any element in the DOM at that point. Just as controller inheritance functions in Rails, any code placed into the “Application” Javascript controller is automatically inherited by other Javascript controllers. This allows for site-wide component configuration, such as a tabbed-navigation widget on every page.

In addition, behaveJS makes it possible to pass arbitrary data from Rails into your Javascript. In your Rails controllers and views you have access to a “session” like object called behaveJS_data. Everything that is placed into this object will be automatically converted to JSON and used by the behaveJS_bootstrap method to initialize behaveJS.

Example:

You now decide that when a person has successfully uploaded their photo, they should be redirected to a different page. To accomplish this without behaveJS, you would have to hardcode the url in the Javascript and that pretty much sucks, especially when a route changes. With behaveJS, you can simply set the url in your Rails controller and access it in the Javascript using the behaveJS.settings object.

In Rails:

class ProfilesController < ApplicationController  
  def edit
    @profile = current_user.profile
    behaveJS_data[:successRedirect] = profile_path(@profile)
    render :action => "edit"
  end  
end

In Javascript:

onUploadSuccess : function()
{
  alert("Thanks for your photo!");
  window.location.href = behaveJS.settings.successRedirect;
}