Search code examples
javascriptjqueryruby-on-railsajaxinstance-variables

How to access changing instance variables (due to a loop) in JavaScript


I am trying to use AJAX to append images to a div container. My photos have a URL field, and so I tried to create an instance variable to then throw inside a div tag like <div id="individual-photo" data-url="<%= @photo_url %>">.

This didn't work, because it assigned one value for that instance variable and when I called it in my .js var url = $("#individual-photo").data("url");, it gave me the same image for all future photos.

I found that solution in another StackOverflow and I think that would work if I wasn't working with a div generated through a loop.. so my question is, seeing as how I am using a loop.. how do I communicate this information to my .js file?

This is the code in my index.html.erb

<div id="sidescrolling-container">
      <% if @page > 1 %>
        <%= link_to "PREV", (next_path(@link - 2) + "/#individual-photo") %>
      <% end %>

      <% @pics.each do |photo| %>
        <% @pic_id = photo.id%>
        <% @photo_url = Photo.where(id: @pic_id)[0].url %>
        <div id="individual-photo" data-url="<%= @photo_url %>">

          <img src="<%= photo.url %>" height='250px' width="250px">
          <span id="photo-title"><%= photo.title %></span>
        </div>
      <% end %>

      <% if @page < @page_max %>
        <%= link_to "NEXT", (next_path(@link) + "/#individual-photo"), id: "next_button" %>
      <% end %>

    </div>

and my .js

var images = $.get("photos/" + page, function(data){
      var info = $("#individual-photo", data).each(function(){
          var title = $("#photo-title", this).text();

          var url = $("#individual-photo").data("url");

          $("#sidescrolling-container").append(
              '<div id="individual-photo"><img src="'+url+'" height="250px" width="250px"><span id="photo-title">'+title+'</span></div>'
            )
      })
    })

If there's a better way to go about this I'd love to know more! Just no gem solutions please, I don't want to use gems for this part of my code.


Solution

  • $("#individual-photo") references every individual photo in your complete DOM, $("#individual-photo").data() always references the data properties of the first element in this selection. Therefore, you always get the the first url.

    It should be

    var images = $.get("photos/" + page, function(data){
        $("#individual-photo", data).each(function(){
            var title = $("#photo-title", this).text();
    
            var url = $(this).data("url");
    
            $("#sidescrolling-container").append(
                '<div id="individual-photo"><img src="'+url+'" height="250px" width="250px"><span id="photo-title">'+title+'</span></div>'
            )
        })
    })