treehouse : what would you like to learn today?
Web Design Web Development iOS Development

[Solved] Adding a coffeescript iteration function to a multi-function script

  • I have the following iteration function:

    $.each $(".main-image"), (index, elem) ->
             console.log $(elem).data("productid")
    

    which pulls out all the <div class="main-image" data-productid="<%= product.id %>"> divs on the page. Each div is assigned a product id via the ruby script <%= product.id %>

    I have a coffeescript function that when hovering a product thumbnail, it switches the main image out with the thumbnail. But right now if you hover a thumbnail it switches out all the main images on the entire page. Thats why I assigned a productid to each and then iterated through each with the above function.

    I was hoping I could just replace console.log with all the existing coffeescript, but its not working.

    Here's my existing coffeescript that is changing every product on the page:

      add_image_handlers = ->
    
    thumbnails = ($ '.product-images ul.thumbnails')
    ($ '.main-image').data 'selectedThumb', 'productid', ($ '.main-image img').attr('src')
    thumbnails.find('li').eq(0).addClass 'selected'
    thumbnails.find('a').on 'click', (event) ->
      ($ '.main-image').data 'selectedThumb', ($ event.currentTarget).attr('href')
      ($ '.main-image').data 'selectedThumbId', ($ event.currentTarget).parent().attr('id')
      ($ this).mouseout ->
        thumbnails.find('li').removeClass 'selected'
        ($ event.currentTarget).parent('li').addClass 'selected'
      false
    thumbnails.find('li').on 'mouseenter', (event) ->
      ($ '.main-image img').attr 'src', ($ event.currentTarget).find('a').attr('href')
    
    thumbnails.find('li').on 'mouseleave', (event) ->
      ($ '.main-image img').attr 'src', ($ '.main-image').data('selectedThumb')
    
    show_variant_images = (variant_id) ->
    ($ 'li.vtmb').hide()
    ($ 'li.vtmb-' + variant_id).show()
    currentThumb = ($ '#' + ($ '.main-image').data('selectedThumbId'))
    if not currentThumb.hasClass('vtmb-' + variant_id)
      thumb = ($ ($ 'ul.thumbnails li:visible.vtmb').eq(0))
      thumb = ($ ($ 'ul.thumbnails li:visible').eq(0)) unless thumb.length > 0
      newImg = thumb.find('a').attr('href')
      ($ 'ul.thumbnails li').removeClass 'selected'
      thumb.addClass 'selected'
      ($ '.main-image img').attr 'src', newImg
      ($ '.main-image').data 'selectedThumb', newImg
      ($ '.main-image').data 'selectedThumbId', thumb.attr('id')
    
      update_variant_price = (variant) ->
    variant_price = variant.data('price')
    ($ '.price.selling').text(variant_price) if variant_price
    

    How can I add my little

    $.each $(".main-image"), (index, elem) ->
    console.log $(elem).data("productid
    

    To that whole file, so that all that coffeescript happens inside of the .each iteration?

    Thanks so much!

  • But right now if you hover a thumbnail it switches out all the main images on the entire page.

    I just sounds like you need to start using a form of $(this) instead of selecting all .main-image divs. So you have this in your mouseenter:

      ($ '.main-image img')
    

    But you should just be doing something like this:

      $(this).find('img')
    

    Or something similar.

  • Wow. I have been stuck on this for two days. And you've gotten me to the point where every image on the page isn't changing! Thank you. However, when you hover a thumbnail it changes the thumbnail out with a big image, not switch the big image out with the thumbnail. Here's my updated coffeescript function:

    add_image_handlers = ->
    
    thumbnails = ($ '.product-images ul.thumbnails')
    ($ '.main-image').data 'selectedThumb', 'productid', $(this).find('img')
    thumbnails.find('li').eq(0).addClass 'selected'
    thumbnails.find('a').on 'click', (event) ->
      ($ '.main-image').data 'selectedThumb', 'productid', ($ event.currentTarget).attr('href')
      ($ '.main-image').data 'selectedThumbId', 'productid', ($ event.currentTarget).parent().attr('id')
      ($ this).mouseout ->
        thumbnails.find('li').removeClass 'selected'
        ($ event.currentTarget).parent('li').addClass 'selected'
      false
    thumbnails.find('li').on 'mouseenter', (event) ->
      $(this).find('img').attr 'src', ($ event.currentTarget).find('a').attr('href')
    
    thumbnails.find('li').on 'mouseleave', (event) ->
      $(this).find('img').attr 'src', ($ '.main-image').data('selectedThumb')
    

    And here's a url to the page: http://pants.telegraphbranding.com/t/women/long-sleeve

    Thanks so much for your help. I very much appreciate it.

  • 1) I would add a class of 'product' to each of the products li.

    Then you can do something like this:

      $(this).parents('.product').find('.main-image img').....
    
  • I'm sorry, I'm not following. Where would you put

    $(this).parents('.product').find('.main-image img') ?
    

    I appreciate your help.

  • Here:

      thumbnails.find('li').on 'mouseenter', (event) ->
          $(this).parents('.product').find('.main-image img').attr 'src', ($ event.currentTarget).find('a').attr('href')
    
  • Thank you so much. I've been scratching my head for two days over this one. Your solution works perfectly. I very much appreciate your time.

  • Awesome!

    You can really bash your head against the wall with this stuff and lose site of the small details. A second pair of eyes usually catches the problem right away.