Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails page-specific JavaScript: What's the best practice?

Anyone who knows about the Rails asset pipeline knows that the default behavior is for all the JavaScript files included in the manifest to get rolled into one large, awkward, unfortunate ball.

ALL THE JAVASCRIPT -> application.js

What this means is that if you have a JavaScript file foo.js, it will activate not only for pages reached by the controller foo, but also for every other page.

This is very easy to work around, but I wonder what is the best way to do it.

I originally had application.html.erb pass the current controller and action to JavaScript in my app using a JavaScript tag.

<%= javascript_tag do %>
  window.givenController = "<%= controller_name %>";
  window.givenAction = "<%= action_name %>";
<% end %>

In my js files, I would then surround page specific code on controller named files with this sort of if statement to ensure that they only ran on those pages.

if(givenController == "foo" && givenAction == "bar"){
  doStuff();
}

My boss contends that this creates unnecessary variables and suggested instead that I use an if statement pointing to specific JQ elements on the page:

if($("#some-element-in-foo").length > 0){
  doStuff();
}

While I'm obviously expected to follow my boss's directions, I'm conflicted about how I should approach this in future apps. I think my approach is more expressive and flexible than the one suggested, but I might be missing some critical flaws.

How do you feel about these two practices, both by themselves and with respect to each other, and why? What might be some better ways of solving this same problem?

like image 525
Vardarac Avatar asked Jun 20 '14 13:06

Vardarac


2 Answers

It's all a matter of preference:

  1. Take care of all elements that are present in the dom regardless of controller/action. Like applying javascript events to navigation elements that are present through an entire application.

  2. Do more targeted javascript logic based on controller/action. Like adding a click event to a particular button that only shows up in this controller and this action.

You most likely will have the need to solve for both cases in an application.

A different approach, more on the lines of yours, would be to add the controller_name and action_name as classes on the body tag <body class="<%= controller_name %> <%= action_name %>">

Then inside your document ready check for the presence of a class: $("body").hasClass("mycontroller");

This would eliminate the complaint your boss has with unnecessary variables.

like image 97
Bill Watts Avatar answered Sep 21 '22 01:09

Bill Watts


There is some info on how to approach this at http://railsapps.github.io/rails-javascript-include-external.html#external. One suggestion from that article is to use the Paloma gem.

like image 40
Eric Levine Avatar answered Sep 19 '22 01:09

Eric Levine