tags:

views:

61

answers:

2

Using jQuery, I'm trying to make a quick & dirty way of changing the innerHtml text of a control button (#ctrlBtn) to reflect the state of div's slideToggle() using the html() method. I can't seem to get my head around it. It changes the button text on the 1st click but then that's it... here's the code:

<script type="text/javascript">
      $(document).ready(function(){
        $("#StatsDetail").slideToggle(); //hide it to start
        $("button").click(function(){
          $("#StatsDetail").slideToggle(); //show/hide 
          // the next line is not working even w/standard if/else syntax...
          ($("#ctrlBtn").html!="Hide") ? $("#ctrlBtn").html("Hide") : "#ctrlBtn").html("View"); 
        }); //end-onClick
      }); //end-onLoad
</script>
<span class="right"><button><div id="ctrlBtn">View/Hide Details</div></button></span>
<div id="StatsDetail"> Lorem ipsum yadda yadda blah </div>

ive even tried

if ($("#statsDetail").is(":visible")) {
    $("#ctrlBtn").html("Hide"); 
 } else { 
    $("#ctrlBtn").html("View");
} 

I know I must be missing something really stupid. Any help would be appreciated.

Joe Negron ~ NYC

+1  A: 

I'll give this a shot:

var ctrlBtn = $("#ctrlBtn");
var statsDetail = $("#StatsDetail");

statsDetail.hide(); //hide it to start

ctrlBtn.click(function(){
  statsDetail.slideToggle();
  ctrlBtn.text( ((ctrlBtn.text() === 'Hide') ? 'View' : 'Hide') );
});

Thing's you'd want to take note of:

  • Always cache your jQuery objects, because creating new ones every time you need to change property is expensive.
  • Use hide() when you're trying to hide something. Not only is it mre immediately obvious what you're doing, you also avoid the animation that comes with the sliding effect (alternatively if you do mean to have the animation, then use slideUp())
  • Your ternary operator was confusing you. Your brackets are not balanced.
  • I would also stop putting the div in the button - it's not valid HTML. Put the id on the button instead, and use display: inline-block
Yi Jiang
Much cleaner. Thanx for the quick response and your optimizations make a lot of sense. I also didn't think to put the ID on the button. I suppose my sloppy coding is one thing but the biggest logic error was the '===' on the conditional and using text() instead of html().
Joe Negron
+2  A: 

This will do what you want using a callback function once the slide animation is finished:

$("button").click(function() {
    $("#StatsDetail").slideToggle(function() {
        $('#ctrlBtn').text($(this).is(':visible')? 'hide' : 'show');
    });
});

The way it works is by executing the defined callback function once the slideToggle is finished on #StatsDetail. It then checks if #StatsDetail is visible and sets the button text() accordingly.

You can see it in action here.

Pat
Awesome! Very elegant use of the callback.I suppose I can also use the ternary ($(this).is(":visible"))? $("#ctrlBtn").text("Hide"): $("#ctrlBtn").text("View Detail");
Joe Negron
Sure, you could use the ternary operator - see my updated example.
Pat
Joe Negron
Yep, the caching would definitely speed up your Javascript, but if you're not running too much of it, you don't need to worry. As for the invalid html, that's your call. If it's being displayed ok and you're not worried about valid code, you can keep it. The one caveat is that valid html will display more consistently across different browsers.
Pat