Macsupport
Macsupport

Reputation: 5444

addClass to a specific DIV when an image icon is clicked

I am trying to implement a JqueryUI button called favorites (id="#favorites") for thumbnails in an image gallery. The button toggles the display of the favorites icon (span class="fav"). I am using Isotope for the thumbnail layout which allows sorting and filtering. What I am trying to do is add a class of "favorites" to the Isotope DIV (class="item") to allow filtering of the images when the "fav" icon is clicked for an individual thumbnail. I also want my favorites icon to stick to each thumb that is marked as a favorite and not toggle after chosen when the JqueryUi button is clicked. So far I am able to make the icons stay visible and add the class to the Isotope DIV except that it adds the class to all DIV's as well as all the favorite icons stay visible. I need to have it only alter the specific DIV and favorite icon of that particular thumbnail. I am still learning jquery and my code is rudimentary and may be totally wrong for this purpose. Any help or direction would be appreciated!

Here is a link: Gallery Clicking the "Fav" button toggles the icons

HTML:

<div class="item">
    <a href="image.jpg" title="Image">
        <img src="image.jpg" width="80" height="80" alt="Image" />
    </a>
    <span class="fav ui-icon ui-icon-heart"></span>
    <div class="title">Image 1</div>
</div>

Button Code:

// JQuery Ui button setup
$( "#favorites" ).button({
    label: "Fav",
    icons: { primary: "ui-icon-heart" }
});

// initially hides the icon
$('span.fav').hide();

//click function to toggle icon under thumbs
$("#favorites" ).click(function() {
    $('span.fav').slideToggle('slow'); 
    return false;
});

// my attempt at adding a class 'sticky' to icon to make it stay visible as well as add class '.favorites' to '.item' div to set it up for filtering
$("span.fav" ).live('click', function() {
    $('.fav').addClass("sticky");

    $('.fav').each(function ()
    {
        $(this).removeClass("fav");
    });  
    $('.item').each(function ()
    {
        $(this).addClass("favorites");
    });  
    return false;
});

I used .live because Isotope is making dynamic changes to the code but this may be not the right thing to do.

Upvotes: 0

Views: 2271

Answers (1)

Groovetrain
Groovetrain

Reputation: 3325

To me it looks like the whole issue may be just an incorrect understanding of the jQuery functions you're using.

$("span.fav" ).live('click', function() {
    // This adds the 'sticky' class to EVERY html element on the page that matches '.fav'
    // $('.fav').addClass("sticky");
    // Try this:
    $(this).addClass("sticky");

    // This is a similar problem here.  You're getting everything that matches '.fav'
    // and you REALLY want just the current item you clicked on.
    /*
    $('.fav').each(function ()
    {
        $(this).removeClass("fav");
    });
    */
    // Try this instead:
    $(this).removeClass("fav");

    // Again, you don't want every '.item', but just the one related to the favorite
    // that you just clicked
    /*
    $('.item').each(function ()
    {
        $(this).addClass("favorites");
    });
    */
    // Do this instead, using $(this) as the DOM element where you're starting from:
    // First, get to the icon's parent, which is the specific 'div.item' you want
    // and then just add the class to that one
    $(this).parent().addClass('favorites');

    // You really only need return false on stuff like <a> tags to prevent
    // them from doing what they would normally want to, and GO somewhere
    // return false;
});

The problem lies simply that you need to be aware of the this variable, which in will reference the current object you're interacting with. In the case of the 'click()' method, this refers to the element that was clicked.

A shorter version of the code would be this (which also allows removing of favorites):

$("span.fav").live('click', function() {
  $(this).toggleClass('sticky')
    .toggleClass('fav')
    .parent()
    .toggleClass('favorites');
});

This takes advantage of jQuery's chaining, allowing you to call method after method on something. Notice only one ';' in the function :)

(Thanks for formatting and commenting your stuff. So much easier to understand and answer!)

Upvotes: 1

Related Questions