views:

1427

answers:

4

I'm trying to create a simple toggling sidebar using jquery, where it expands and contracts when a button is pressed. The button also changes to another type of button when pressed. The sidebar will expand, but for some reason, it will not move back to it's original position. You can see a copy of the javascript and html at http://www.jqueryhelp.com/viewtopic.php?p=4241#4241

Here is the working code, thanks Bendeway! :D

$(".btn-slide").live('click', function(e){ 
   e.preventDefault();

   $("#sidebar").animate({opacity: "show", left: 250}, "slow"); 
   $(this).toggleClass("btn-slide").toggleClass("active");
}); 

$(".active").live('click', function(e){ 
   e.preventDefault();

   $("#sidebar").animate({opacity: "hide", left: 100}, "slow"); 
   $(this).toggleClass("btn-slide").toggleClass("active");
});
+3  A: 

try instead of right use left with a negative number. in addition I would recommend using preventDefault instead of returning false.

$(".active").click(function(e){ 
   e.preventDefault();

   $("#sidebar").animate({opacity: "hide", left: -250}, "slow"); 
   $(this).toggleClass("btn-slide");
});

Update

Another piece i just noticed is that your attaching a click event to the .active button, when the document is ready, but there is no .active button when the document is ready that comes in after you change it. There are a couple options here.

First is to use the new live feature of jquery 1.3

$(".btn-slide").live('click', function(e){ 
   e.preventDefault();

   $("#sidebar").animate({opacity: "hide", left: 250}, "slow"); 
   $(this).toggleClass("btn-slide").toggleClass("active");
}); 

$(".active").live('click', function(e){ 
   e.preventDefault();

   $("#sidebar").animate({opacity: "hide", left: -250}, "slow"); 
   $(this).toggleClass("btn-slide").toggleClass("active");
});

The other option would be to have set the click event on a different modifier (eg. on the id, maybe).

<span>News  <img src="img/overlay.png" id="sliderButton" class="btn-slide" alt="" /></span>

then use this to handle the click

$("#sliderButton").click(function(e){ 
  e.preventDefault();

  $(this).is('.btn-slide').each(function() {
   $("#sidebar").animate({opacity: "show", left: 250}, "slow"); 
  });

  $(this).is('.active').each(function() {
   $("#sidebar").animate({opacity: "hide", left: -250}, "slow"); 
  });
  $(this).toggleClass("active").toggleClass('btn-slide');  
});

or even more concise

$("#sliderButton").click(function(e){ 
  e.preventDefault();

  var animationSettings = {opacity: "show", left: 250};
  if ($(this).hasClass('active') )
  {
    animationSettings = {opacity: "hide", left: -250};
  } 

  $("#sidebar").animate(animationSettings , "slow"); 
  $(this).toggleClass("active").toggleClass('btn-slide');  
});

The final option that I can think of would be to set the click events after you change them, but I wouldn't do that so I'm not going to supply a sample.

Lastly, I would put in alert into your active callback and make sure that your active button event is actually firing.

bendewey
nope, it doesn't move the sidebar back. :(
There we go, with a bit of modding that and the CSS,the first update works! I'll post the working script in a second, thanks. :)
A: 

The way your logic is written, I think you need to do a 'toggleClass' on both classes inside your click handlers which will add one and remove the other. For example, when your "active" item is clicked you toggle (add) the btn-slide class, but this will leave the "active" class in place too.

Of course instead of using "toggleClass" you could also use "addClass" and "removeClass" to be more explicit.

I recommend using a tool like Firebug to watch what's happening inside your DOM.

$(document).ready(function(){

   $(".btn-slide").click(function(){
   $("#sidebar").animate({opacity: "show", left: "250"}, "slow");
   $(this).toggleClass("active");  // add class
   $(this).toggleClass("btn-slide"); // remove class
   return false;
   });   

});

$(document).ready(function(){

   $(".active").click(function(){
   $("#sidebar").animate({opacity: "hide", right: "250"}, "slow");
   $(this).toggleClass("active");  // remove class
   $(this).toggleClass("btn-slide");  // add class
   return false;
   });
});
Joe Holloway
It doesn't move it back. I've been playing around with it a bit more, and come across nothing.
Suggestion: instead of using animate, start with very simple hide() and show() just to make sure your event handlers and basic logic is working correctly. If it works, then figure out why your animate call is broken.
Joe Holloway
A: 

This works.

$(document).ready(function(){
    $(".btn-slide").click(function(){
     $("#sidebar").slideToggle("slow");
     $(this).toggleClass("active"); return false;
    });
});
superUntitled
A: 

The HTML

<div id="content">
 <a href="#" id="ec">Expand / Contract</a>
 <div id="main">
   Watch Me Shrink Or Grow
 </div>
</div>

The Jquery

$(function() {
 var ecswitch = 1;
 /* prevent the annoying scroll back up thing */
 $("#ec").click(function(e) {
   e.preventDefault();
   var x = $("#main").width(); // get element width
   var y = $("#main").height(); // get element height 
   if(ecswitch == 1) {
    $("#main").animate({opacity:0, hieght:"0", width:"0"}, 1300);
    ecswitch = 0;
   } else {
     $("#main").animate({opacity:1, hieght:y, width:x}, 1300);
    ecswitch = 1;
   }
 });
});

The CSS

#main { height:200px; }

Explanation

OK I chose to do this a little differently. this initializes with the height of our experiment being 200px and the width is automatic. When you click the hyperlink the experiment is hidden in 1.3 seconds and a switch is set to 0. when you click again it comes back over a period of 1.3 seconds and the switch gets set back to 1. like a light switch. I used the animate here because a simple fade or hide got me bored...

The reason why I got the widths and heights of the element before zero-ing them was if said width:100%" and hieght:"100%" in my animate it would set it to 100% of the pages width and height...we don't want that.

NOTE : I am also using the opacity over a time period. quite nice for fading as well :)