5

I'm partially new to RoR and fairly new to jQuery. Currently, I have a working RoR site as a learning platform. I want to include some jQuery basic features to expand my learning (.mouseenter(), .hover(), .fadeIn() etc).

Let me set the scene with some code (I've snipped parts to keep it short):

$ ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux]
$ rails -v
Rails 3.2.8

Gemfile:

gem 'jquery-rails'

config/routes.rb:

root to: 'static_pages#home'

app/controllers/static_pages_controller.rb:

def home
    @Presents = Present.all.reverse.take(20)
end

app/views/layouts/application.html.erb:

<!DOCTYPE html>
    <html>
        <head>
            <title>List</title>
            <%= stylesheet_link_tag    "application", :media => "all" %>
            <%= javascript_include_tag "application" %>
            <%= csrf_meta_tags %>
            <%= render 'layouts/shim' %>
        </head>
        <body>
            <div class="container-narrow">
                <%= render 'layouts/header' %>
                <%= yield %>
            </div>
        </body>
    </html>

app/assets/javascripts/application.js:

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .

app/views/static_pages/home.html.erb:

<div class="jumbotron">
    <h1>Heading</h1>
</div>
<%= render 'shared/list' %>

app/views/shared/_list.html.erb:

<% if @Presents.any? %>
    <%= render partial: 'shared/list_item', collection: @Presents %>
<% end %>

app/views/shared/_list_item.html.erb:

<div id="present">
    <ul id="<%= list_item.id %>">
        <span class="content">
            Some content here
        </span>
</div>

Ideally, I want my jQuery to effect the <div> with id="present". Here is my test jQuery:

$(document).ready(function(){
    $('#present').mouseenter(function(){
        $(this).fadeIn('fast',1);
    }
    $('#present').mouseleave(function(){
        $(this).fadeIn('fast',0.5);
    }
});

Currently, I have the above stored app/views/static_pages/home.js.erb and nothing happens. Is this an appropriate location? Or should I shift it to the app/views/shared/ directory?

From my rendered site page - is there a way to check if my jQuery is being included and executed? I feel my current blocking point is the location of my home.js.erb.

Edit: errors detected in my jQuery - corrected below:

jQuery:

$(document).ready(function(){
    $('#present').mouseenter(function(){
        $(this).fadeTo('fast',1);
    });
    $('#present').mouseleave(function(){
        $(this).fadeTo('fast',0.5);
    });
});

and correct use of fadeTo. fadeIn doesn't accept a second argument for opacity as I was trying.

SinFulNard
  • 173
  • 2
  • 2
  • 10

1 Answers1

9

You should make a file within app/assets/javascripts/ name after the controller that the view is associated with, for example for a controller named home it would be: app/assets/javascripts/home.js then within your application.js file include it into the asset pipeline as so:

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require home

But since you already have //=require tree . the above modification to application.js should not be necessary but I would suggest doing it as above and include all of your files singularly so that you can have more control over when your JS is included.

Edit: Also, I would suggest changing the binding you are using from an ID to a Class incase you want to reuse this functionality.

For Testing purposes to see if the JS is being executed you can add something like:

$(document).ready(function(){
    $('#present').mouseenter(function(){
        alert("MouseEnter!"); // This will create an alert box
        console.log("MouseEnter!"); // This will log to the JS console on your browser which is a bit nicer to read than alerts, you do not need both, just preference
        $(this).fadeIn('fast',1);
    }
    $('#present').mouseleave(function(){
        alert("MouseLeave!"); // This will create an alert box
        console.log("MouseLeave!");
        $(this).fadeIn('fast',0.5);
    }
});

This is only to test the JS quick, you should never leave these in your code of course.

Also, after taking a second look at the JS you may want to try something like this:

$(document).ready(function(){
    $('#present').mouseenter(function(){
        $(this).fadeIn('fast',1);
    }).mouseleave(function(){
        $(this).fadeIn('fast',0.5);
    });
});

note the closing );

Jay Truluck
  • 1,509
  • 10
  • 17
  • Thanks Jason. I shifted to this location and have tried again to no success. My controller is 'static_pages' but renders a 'shared' file - would the name still remain as static_pages.js? Is the name an important factor? – SinFulNard Jan 17 '13 at 03:16
  • That should work, the name itself is not really the important part though (they are just arbitrary I included it for good practice) the main portion is the inclusion with the asset pipeline. As long as it is included there and you are utilizing it the JS should be included, could you include your application.html.erb file so we could see what JS you are including there? – Jay Truluck Jan 17 '13 at 03:36
  • Ok, thanks for clearing up the naming scheme. I've kept the //=require tree . in place to ensure I'm not missing it from the pipeline. I've made an edit including the entire app/views/layouts/application.html.erb. – SinFulNard Jan 17 '13 at 03:45
  • hmmm it looks like everything is as it should be from what you have included, to test out if it is being loaded you can load you page in a browser of your choice then with developer tools inspect the page and see if the javascript is part of your application.js file that is returned from the server. Also, something you may want to try is adding something like `alert("MouseEnter");` or `console.log("MouseEnter")` within your mouseenter jQuery functions to make sure that if the JS is being loaded that the events are triggering as expected. I will update my answer to have an example. – Jay Truluck Jan 17 '13 at 03:51
  • Jason - champ. We both managed to glean over errors in my js (which were propagated into your code as well). I haven't closed my function calls correctly! But you've shown the setup isn't the problem. I think I'm clashing with something else CSS related. Thanks a ton for your persistence here. – SinFulNard Jan 17 '13 at 04:24
  • Urgh, not to mention I had the wrong function call anyway. What the code required was fadeTo not fadeIn. Now I've discovered the Chrome developer console all my woes are clear. – SinFulNard Jan 17 '13 at 04:34
  • Ah! that is great to hear chrome can be a life saver for sure! – Jay Truluck Jan 17 '13 at 05:22