0

I have a section of ERB code in my view that fetches an array of image objects and creates a grid of thumbnails. I want to use jQuery's fadeIn and fadeOut functionality to cycle the thumbnails on and off. I've looked at other examples of how to set this up, but my code is still not working.

The number of images in the array is dynamic, so I have to set my tag id's dynamically. That part of the code seems to be working. All images are set to

I then have a jQuery script which should cycle through the images by fading them in and out. So far as I can tell, the script looks right. Yet for some reason it doesn't execute when the page renders. None of my variables nor the function are defined in the console. There are no errors either.

<div class="media-container top gallery-container" style="margin:-12px;height:200px;">
    <% c.photos.each_with_index do |m,i| %>
    <a href="<%= m.image.url %>">
        <div class="gallery-photo" id="photo_<%= "#{c.id}_#{i}" %>" style="z-index:<%= 10+i %>;position:absolute;width:100%;height:100%;background-image: url('<%= m.image.url(:medium) %>');">
        </div>
    </a>
    <% end %>
    <br style="clear:both" />

    <% length = c.photos.length %>
    <% galleryID = c.id %>
    <%= javascript_tag do %>
        $(document).ready(function(){
            var length = '<%= length.to_json.html_safe %>';
            var galleryID = '<%= galleryID.to_json.html_safe %>';

            var runSlide = function(g, p) {
                $('#photo_' + g + '_' + p)
                    .fadeOut(1500)
                    .delay(3500)
                    .fadeIn(1500);
                };
            for (var i = 0; i < length; i++) {
                runSlide(galleryID, i);
            }
        });
    <% end %>
</div>

My problem is that I can't figure out why the script isn't running. Ideally the script would not be placed where it is, however it depends on the value of length and galleryID, which are only available within the context of the Ruby loop.

Daniel Bonnell
  • 4,817
  • 9
  • 48
  • 88
  • not directly related to an answer, but if you want your script to live in assets/javascripts, you can add length and galleryID as data attributes in your template and reference that in your javascript. For example the div would have `data-length= "#{c.photos.length}"` and `data-gallery-id= "#{c.id}"` – Mario May 06 '15 at 20:20
  • I tried that approach as well, but the script is still not executing upon page load completion. – Daniel Bonnell May 06 '15 at 20:25

3 Answers3

0

That while (true) loop will never stop running, so its likely stuck there. I think you can just get rid of the outer while loop and leave the for loop in place.

infused
  • 24,000
  • 13
  • 68
  • 78
  • That's not the cause of the problem. The problem is that nothing inside my `<%= javascript_tag do %>` is executed. Even if I strip out all the other code and just define a dummy variable `var test = 123;`, and then load the page, `test` is not defined in the console. – Daniel Bonnell May 06 '15 at 19:19
0

You have an extra ; in there that's causing your script to fail. Line 7 of your JS

                $('#photo_' + id + '_' + i)
                .fadeOut(1500); <<<<----------- HERE
                .delay(3500)
                .fadeIn(1500)

also, to be able to move your JS to a more sane place, you can add length and galleryID as data attributes in your template and reference that in your javascript. For example the div would have data-length= "#{c.photos.length}" and data-gallery-id= "#{c.id}"

Mario
  • 1,349
  • 11
  • 16
  • Well, I fixed the syntax errors, but again, that doesn't get to the root of the problem. The problem is that nothing inside the javascript_tag block is executed. Even if I delete everything and just put `var test = 123;`, `test` will be undefined in the console when I reload the page. – Daniel Bonnell May 06 '15 at 20:37
  • if you put `$(document).ready(function(){ alert('test'); });` it doesn't work? – Mario May 06 '15 at 20:43
  • As I said, "The problem is that nothing inside the javascript_tag block is executed." – Daniel Bonnell May 06 '15 at 20:53
  • @ACIDSTEALTH You get nothing in your JS console? No errors at all? Usually when nothing gets executed it points to a JS error somewhere. – Mario May 06 '15 at 21:06
  • No console errors. No server log errors. No missing (failed to load) resources in the Network tab of the inspector. Nothing. There are no stack traces, errors, or clues anywhere. It's as if the browser simply doesn't recognize that it is a script. – Daniel Bonnell May 06 '15 at 21:22
  • How does the javascript tag show up in your HTML source? Maybe there's a clue there. Could you share it please? – Mario May 06 '15 at 21:29
  • Just looks like a normal script tag to me. I'm not sure what the CDATA tag is for though or how that got there. – Daniel Bonnell May 07 '15 at 02:31
  • Never mind, apparently the CDATA tags are a normal fixture with inline ` – Daniel Bonnell May 07 '15 at 02:55
0

I figured out why the script wasn't running, or at least how to get around that problem. I first saved my Ruby variables from the loop and then moved my script to the bottom of the partial. Since I have my Ruby variables saved, the script can now be placed anywhere in the partial after those variables are defined.

That seemed to do the trick.

I'm still not sure why the script wouldn't execute when it was placed higher in the code.

Within my loop, I added this code:

<% @gallerySize = c.photos.length.to_i %>
<% @galleryID = c.id.to_i %>

And then my script can access that data at the bottom of the partial:

<%= javascript_tag do %>
    $('#media-gallery').ready(function(){
        var gallerySize = parseInt('<%= @gallerySize %>');
        var galleryID = parseInt('<%= @galleryID %>');
        var i = 0;

        var runSlide = function(g, p) {
            $('#photo_' + g + '_' + p).fadeOut(1500).delay(3500).fadeIn(1500);
        };
        setInterval(function() {
            runSlide(galleryID, i);

            if (i === gallerySize) {
              i = 0;
            } else {
              i++;
            }
        }, 7500);
    });
<% end %>
Daniel Bonnell
  • 4,817
  • 9
  • 48
  • 88