0

I have a list of images showing and each image got a list of 1 or more additional thumbnail images.

When use hovers on one of the additonal images, the main image has to change with that addional image's source, and when mouse leaves that thumbnail, the original main image source comes back.

I managed to make it work but it only updates the source with the last thumnbail in found in the loop, so I'm basically stuck here is my code which is not working at the moment

<div>
    <img class="mainImg" src="http://mysource.com/img.jpg"/>
</div>

<div class="additionalImg">

     <?php
     $product = Mage::getModel('catalog/product')->load($_product->getId());
     /* getting additional images url */
    foreach ($product->getMediaGalleryImages() as $image) {?>

    <!-- thumbnails -->
        <a href="<?php echo $image->getUrl();?>">
            <img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $image->getFile())->resize(60, 60); ?>" 
            width="60" height="60" alt="" title="" />
        </a>
    <!-- end thumbnails -->

    <script>
    // var newSrc = jQuery('.additionalImg a img').attr('src');
    jQuery('.additionalImg a').hover(function(){
            jQuery('.mainImg').attr("src", newSrc)
        });
    </script>

        <?php };?>
</div>

Thanks a lot

mlclm
  • 725
  • 6
  • 16
  • 38

3 Answers3

2

UPDATE: The markup shown in your codepaste is invalid because you have duplicate id attributes in your container divs. You didn't make it clear in your original question that all of the code shown was repeated several times. Change each id="product" to class="product" and the following code will work:

jQuery(document).ready(function() {
    jQuery('.mainImg').each(function() {
        $(this).data("original", this.src);                
    });

    jQuery('.additionalImg a img').hover(function () {
        jQuery(this).closest('.product').find('.mainImg').attr("src", this.src);
    },function() {
        var $main = jQuery(this).closest('.product').find('.mainImg');
        $main.attr("src", $main.data("original"));
    });
});

Demo: http://jsfiddle.net/s9Rhx/2/

Include the above JavaScript once on your page, not once per product div.

The above works by firstly looping through all of the mainImg divs and storing their original default image src. Then it binds the event handler directly to the img elements in the thumbnail anchors. On hover it uses .closest() to navigate up to the containing class="product" div (don't forget to change the id to a class), then .find() to get back down to the mainImg div within the current container.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • @AamirAfridi - I thought the anchor had the full-size image URL but the img in the anchor had the thumbnail sized image. That's what the PHP code seems to be doing. – nnnnnn Jan 21 '14 at 11:07
  • Thanks but this solution didn't work for some reason. Aamir Afridi's solution worked but every .mainImg images sources on the page are replaced by the thumnbail source, not only the current image's thumbnails being hovered...Please look at the code that is outputed here: http://codepaste.net/pm47b8 – mlclm Jan 21 '14 at 11:47
  • I didn't realise that all of the above was repeated on your page. That changes things. Also the code at your codepaste.net link is not what your above PHP would output, because e.g., the thumbnail anchors don't have images specified in their src like in your PHP above. Anyway, answer updated to work with the code in your codepaste. – nnnnnn Jan 21 '14 at 12:15
  • Sorry my fault, I'm a little tired and didn't notice... THANKS your solution is working. One thing though, how could I make the main image source come back to its original image source when mouseleaves the thumbnail ? Is there a way to use toggle() or should it be mouseleave or else ? – mlclm Jan 21 '14 at 12:28
  • There are various ways to allow for default image sources getting restored when the mouse moves out - I've updated my answer using the first method that came to mind. – nnnnnn Jan 22 '14 at 09:14
  • I answered the the question (below) and I looked at your answer and this demo http://jsfiddle.net/s9Rhx/2/ I was shocked how close our answers are :D – Aamir Afridi Jan 22 '14 at 12:05
  • @nnnnnn thanks a lot for your help and neat solution. Works like a charm. Will study your bit of code to to do it myself next time. Cheers – mlclm Jan 27 '14 at 14:54
2

First you have multiple IDs on same page which is wrong. I changed each id to class so it become class="product"

Complete demo: http://jsbin.com/AWoNimO/2/edit

Demo HTML as you provided - I have added few dummy images for the demo:

<div class="product">   <a href="http://link.to/">
      <img class="mainImg" src="http://lorempixel.com/output/fashion-q-c-60-60-8.jpg"/>
    </a>

    <div class="additionalImg"> <a class="thumb" href="#">
                <img class="productImg" width="60" height="60" title="" alt="" src="http://lorempixel.com/60/60/sports/">
            </a>
    <a class="thumb" href="#">
                <img class="productImg" width="60" height="60" title="" alt="" src="http://lorempixel.com/60/60/city/">
            </a>
    <a class="thumb" href="#">
                <img class="productImg" width="60" height="60" title="" alt="" src="http://lorempixel.com/60/60/animals/">
            </a>

    </div>
</div>
<hr>
<div class="product">   <a href="http://link.to/">
      <img class="mainImg" src="http://lorempixel.com/output/fashion-q-c-60-60-2.jpg"/>
    </a>

    <div class="additionalImg"> <a class="thumb" href="#">
                <img class="productImg" width="60" height="60" title="" alt="" src="http://lorempixel.com/60/60/cats/">
            </a>
    <a class="thumb" href="#">
                <img class="productImg" width="60" height="60" title="" alt="" src="http://lorempixel.com/60/60/nature/">
            </a>
    <a class="thumb" href="#">
                <img class="productImg" width="60" height="60" title="" alt="" src="http://lorempixel.com/60/60/food/">
            </a>

    </div>
</div>

Javascript:

$(function(){
  $('.mainImg').each(function(){$(this).data('original', this.src)});
  $('.thumb img').hover(
    function(){
      $(this).closest('.product').find('.mainImg')[0].src = this.src;
    },
    function(){
      var $mainImg = $(this).closest('.product').find('.mainImg');
      $mainImg[0].src = $mainImg.data('original');
    }
  )
});
Aamir Afridi
  • 6,364
  • 3
  • 42
  • 42
  • I have moved the js script outside the loop. This is working but it will change the source for every .mainImg images on the page. Please look at the code that is outputed here: http://codepaste.net/pm47b8 – mlclm Jan 21 '14 at 11:43
0

Try this:

<div>
    <img class="mainImg" src="http://mysource.com/img.jpg"/>
</div>

<div class="additionalImg">

     <?php
     $product = Mage::getModel('catalog/product')->load($_product->getId());
/* getting additional images url */
foreach ($product->getMediaGalleryImages() as $image) {?>

<!-- thumbnails -->
    <a href="<?php echo $image->getUrl();?>">
        <img src="<?php echo $this->helper('catalog/image')->init($_product, 'thumbnail', $image->getFile())->resize(60, 60); ?>" 
width="60" height="60" alt="" title="" />
</a>
<!-- end thumbnails -->

    <?php };?>

    <script>
        $(function () {
            var thumbs = $('.additionalImg a');
            if (thumbs.length > 1) {
                thumbs.each(function () {
                    $(this).hover(function () {
                        $('.mainImg').attr("src", $(this).attr("href"));
                    });
                });
            }
        });
    </script>

</div>
Thiago Vinicius
  • 170
  • 1
  • 10
  • Note that you don't need the `.each()` loop: you can just say `thumbs.hover(...)` and it will bind a separate handler to all elements in `thumbs`. Why are you checking if the `.length` is greater than 1? – nnnnnn Jan 21 '14 at 11:10
  • You're right but since I've faced some problems with .each() before I always check if it has more than 1 element before using it. Because that was the problem when I had only 1 element it would crash my script while calling .each(). – Thiago Vinicius Jan 21 '14 at 11:53