tags:

views:

508

answers:

3

I have a 'link' that, when clicked, will show a div full of content. Once clicked, the 'Open' button changes to a 'Close' button with close functionality.

Here's the jQuery:

$(document).ready(function(){


 $('.open_user_urls').click(function() {
            $('#user_urls').slideDown('slow');
            $('.open_user_urls').addClass('close_user_urls');
            $('.open_user_urls').removeClass('open_user_urls');
            $('.close_user_urls').html('Close Search History');
            return false;
        }
    );

    $('.close_user_urls').click(function() {
            $('#user_urls').slideUp('slow');
            $('.close_user_urls').addClass('open_user_urls');
            $('.close_user_urls').removeClass('close_user_urls');
            $('.open_user_urls').html('Show Search History');
            return false;
        }
    );

});

It works as expected on the first click. The div is shown, the html content is changed to the new text, and the class is changed on the link.

But clicking again to close it does nothing. If I paste the .close__user_urls click function into the Firebug console, run it, and then click, it closes as expected.

Any ideas?

+1  A: 

I believe the second function is applied only to the elements that have that CSS class '.close_user_urls', which is 0 initially.

In older versions of jQuery, the livequery plugin will let jQuery keep track and add/remove the click events as items get and lose the css classes. In newer versions this is built in, as mentioned in the above answer.

Tom Ritter
You don't even need to use livequery if you're using jQuery 1.3.1, I believe.
nickohrn
i updated to test this, but, with my current code at least, this is not the case. will try with the .live function noted in another answer.
Ian
+6  A: 

The class $('.close_user_urls') does not exist when the page is populated - so it does not exist when it's click is bound on $(document).ready().

The easiest way to accomplish this with jQuery 1.3.2 will be to use a "live" function instead:

$(document).ready(function(){
   $('.open_user_urls').live('click', function() {
       $('#user_urls').slideDown('slow');
       $(this).addClass('close_user_urls');
       $(this).removeClass('open_user_urls');
       $(this).html('Close Search History');
       return false;
   });

   $('.close_user_urls').live('click', function() {
       $('#user_urls').slideUp('slow');
       $(this).addClass('open_user_urls');
       $(this).removeClass('close_user_urls');
       $(this).html('Show Search History');
       return false;
   }); 
)};

Live functions bind the specified event to all current and future matching elements.

Peter J
+1  A: 

I would do this differtly:

$(document).ready(function(){
    $('.open_user').click(function() {
     var link = $(this);
     if (link.hasClass('opened')) {
      link.removeClass('opened').text('Show Search History');
      $('#user_urls').slideUp('slow');
     } else {
      link.addClass('opened').text('Close Search History');
      $('#user_urls').slideDown('slow');
     }
     return false;
    }
);
glavić