5

I am using a javascript file named text_messages.js i would like this to only be used in my text_messages\new.html.erb page.

Right now when i get in any other page in my project in my console I get the error:

error

this error is happening because I am running the text_messages.js in every page which is what i am trying to prevent. Thank you!

4 Answers 4

7

You can use stub to tell Rails what's the file you don't want load despite using require_tree ..

For instance if your file text_message.js is in the app/assets/javascripts folder, then you can add the stub to your application.js file like:

...
//= require_tree .
//= stub 'text_message'

Then add your file to the precompile assets in your config/initializers/assets.rb, like:

Rails.application.config.assets.precompile += %w( text_message.js )

And then add it manually to your new.html.erb:

<%= javascript_include_tag 'text_message' %>

You need to restart your server with every change in the assets file.

Sign up to request clarification or add additional context in comments.

1 Comment

This was awesome! Thanks!
1

Add the following line to assets.rb

Rails.application.config.assets.precompile += %w(path/to/text_messages.js)

Remove the entry for this file from application.js

Now include this file on text_messages\new.html.erb page

<%= javascript_include_tag 'path_to_text_messages.js' %>

Restart you server

Comments

1

So I think there are a few ways of doing this. you can put the javascript inline on the page and it will only be loaded there, or you can put a link to that javascript file on that page specifically. but if you put it in your assets folder I believe it will be loaded by all pages. I think the other solutions are the proper way of doing it though.

2 Comments

Thanks for the reply! do you have any example code you can share? @
well for example you can just put this on any page <script> alert("hello world") </script> I must warn you, that even though this will work. its really lazy and i think if you are working with other rails developers they might get annoyed by the solution. but it should work.
1

The quick and dirty way would be to just add the script to the html of the page you need it on, but that's probably a bad idea.

You likely want a more comprehensive solution:

There is a very good answer to this at http://brandonhilkert.com/blog/page-specific-javascript-in-rails/.

Basically, you want to open your app/views/layouts/application.html.erb and convince it to give you controller and view information each time it renders a page. Then you can use that information to load page or controller specific scripts.To do so you change the body tag in application.html.erb from

<body> 
  <%= yield %>
</body>

to

<body class="<%= controller_name %> <%= action_name %>">
  <%= yield %>
</body>

So, when rails renders the body tag it will now add a class for the controller and one of the actions in the controller.

Say you have a controller called static_pages, and the static_pages controller has home defined in the controller and a view in the views. Controller will have this:

def home 
end 

When rails renders the view/page home.html.erb it will now add to the body tag a class of static_pages and a class of home.

<body class="static_pages home">
    the home view is rendered here
</body>

This will be a site wide change, so if you go to an index page/view from the users controller the body tag would be:

<body class="users index">
    the index view is rendered here
</body>

Now, make a file called vendor/assets/javascripts/jquery-readyselector.js containing:

(function ($) {
  var ready = $.fn.ready;
  $.fn.ready = function (fn) {
    if (this.context === undefined) {
      // The $().ready(fn) case.
      ready(fn);
    } else if (this.selector) {
      ready($.proxy(function(){
        $(this.selector, this.context).each(fn);
      }, this));
    } else {
      ready($.proxy(function(){
        $(this).each(fn);
      }, this));
    }
  }
})(jQuery);

That file must be properly referenced in application.js

...
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require jquery-readyselector
//= require_tree . 

Once all that is done you can test it by making a simple alert specific to the view you want test like so:

// app/assets/javascripts/static_pages_home.js

$(".static_pages.home").ready(function() {
  return alert("You should only see this on the static pages home page.");
});


// app/assets/javascripts/user_index.js

$(".users.index").ready(function() {
  return alert("You should only see this on the users index page.");
});

You could also make a script controller specific by not referencing the action/view, only the controller.

$(".users").ready(function() {
  return alert("You should only see this on a users controller controlled page.");
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.