hyphen
hyphen

Reputation: 967

Jquery code produces undesirable result

I have an FAQ page, where I want the answer to the question to slide down from underneath the question. I also want a plus sign to appear before the question is clicked, and a minus sign to appear when the answer is visible. Unfortunately my jquery code changes the plus/minus sign on all the questions, not just the one clicked. here's my code:

$('.trigger').click(function() {
   $(this).children('.hidden').toggle('slow', function() {
       if ($(this).is(':visible')) {
            $('li p a').children('.plus').hide();
            $('li p a').children('.minus').show();
        } else {
            $('li p a').children('.plus').show();
            $('li p a').children('.minus').hide();
        }
   });
    return false;
 }); 

and a jsfiddle example:

jsfiddle

Upvotes: 0

Views: 121

Answers (2)

George Reith
George Reith

Reputation: 13476

Your current selector $('li p a') searches the entire document for anchors which are children of an li which is a child of a paragraph. You need to ensure that you are only searching within the .trigger element.

See http://api.jquery.com/find/

$('.trigger').click(function() {
   var trigger = $(this); // Store the clicked object in a variable and convert to jQuery object
   trigger.children('.hidden').toggle('slow', function() {
       if ($(this).is(':visible')) {
            trigger.find('.plus').hide(); // trigger.find() allows us to search using our CSS selector only within the trigger object.
            trigger.find('.minus').show();
        } else {
            trigger.find('.plus').show();
            trigger.find('.minus').hide();
        }
   });
    return false;
 }); 

http://jsfiddle.net/NYZa3/1/

Can also be written like this:

$('.trigger').click(function() {
   var trigger = $(this); // Store the clicked object in a variable and convert to jQuery object
   trigger.children('.hidden').toggle('slow', function() {
       trigger.find('.plus, .minus').toggle();
   });
   return false;
 }); 

http://jsfiddle.net/NYZa3/4/

Or the entire thing can be chained (the .plus and .minus will toggle as soon as clicked instead of after show/hide animation is completed):

$('.trigger').click(function() {
   $(this)
   .children('.hidden')
   .toggle('slow')
   .siblings('p')
   .find('.plus, .minus')
   .toggle();
    return false;
}); 

http://jsfiddle.net/NYZa3/5/

Upvotes: 2

Ludo237
Ludo237

Reputation: 1717

You should determine witch "minus" and "plus" are children of.

$('.trigger').click(function() {
    var tis = $(this);
    tis.children('.hidden').toggle('slow', function() {
       if ($(this).is(':visible')) { // $(this) in "this" case is refer to the children!
            tis.find('.plus').hide();
            tis.find('.minus').show();
        } else {
            tis.find('.plus').show();
            tis.find('.minus').hide();
        }
   });
    return false;
 }); 

I know this code need to be more clear but it works know :-) I Always encourage to cache the DOM object if you are going to use a lot in the JQuery action. A very basic caching is to create a temp variable and put all the DOM (ex $(this)) inside so you can use it in every step of your action.

Upvotes: 2

Related Questions