views:

105

answers:

4

I'm fairly new to jQuery and I'm having trouble with an animation that I'd like to do.

Say I have some drops downs to filter content that use this HTML:

<table class="calFilter">
    <tr>
     <th>
      <label for="ddlDept">Show events hosted by:</label>
     </th>
     <th>
      <label for="ddlEventType">Select event type:</label>
     </th>
    </tr>
    <tr>
     <td>
      <select name="ddlDept" id="ddlDept" class="deptDropDown">
       <option value="">All</option>
       <option value="cfys">Community, Family, &amp; Youth Services</option>
       <option value="conser">Conservation Board</option>
       <option value="emergm">Emergency Management</option>
       <option value="health">Health Department</option>
      </select>
     </td>
     <td>
      <select name="ddlEventType" id="ddlEventType">
       <option value="0">All</option>
      </select>
     </td>
     <td>
      <input type="submit" name="cmdGo" value="Go" id="cmdGo" />
     </td>
    </tr>
</table>

If you select a different department, the event types no longer make sense, so I'd like to hide the Event Type label and drop down when the Dept drop down changes. I got this to work using the change event callback for the drop down and the simple hide() command.

But if I try to use animation, things go haywire. The controls don't slide the way I would expect, the animation occurs every time even if the controls are already hidden, etc.

I would like some sort of nice fade or slide, or some combination of those two. How would you do this?

A: 

Try using slideDown() instead of hide() or see one of the many other built in show/hide animations at jquery.com

If it's still animating while it's already hidden, add something like this in your code:

if($('select#ddlEventType').not(':hidden')){
      $(this).slideDown();
}
idrumgood
A: 

You should first check if it is visible or not:

// Callback function
function() {
    var obj = $(this);
    if (obj.is(':visible')) { // make sure you're checking the visibility of one or both of the objects that are being hidden
        // hide
    } else {
        // show
    }
}
jeef3
I tried that, but it wasn't working. I think it's because I didn't include the .hide() at the end of the animation.
Shea Daniels
+1  A: 

Tables are pretty finicky when it comes to animation. fadeOut should work with tables, you'll have mixed results on different browsers with a lot of the other effects.

Andy Gaskell
+1  A: 

I think it's because you have the elements in a table layout that the animation is acting funny. To overcome this, you can hide the <td> elements that the elements you wish to hide are in as well.

Here's a Working Demo that is tested and works in Firefox 3.5 and IE6. Add /edit to the URL if you want to play around with it.

The code from the demo

$(function() {

    $('#ddlDept').change(function() {
      var label = $('label[for="ddlEventType"]');

      if (label.is(":visible")) {  
          label.parent().animate({ width: "0px" }).hide().end().hide();
          $('#ddlEventType').parent().animate({ width: "0px" }).hide().end().hide();
      }
    });

});

EDIT:

As discussed in the comments, here's a Working Demo that uses fadeTo() to first fade the elements before animating and hiding.

The code from the demo

$(function() {

    $('#ddlDept').change(function() {
      var label = $('label[for="ddlEventType"]');
      var select = $('#ddlEventType');

      if (label.is(":visible")) {  
          label.fadeTo("slow", 0.01, function() { 
                  label.parent()
                       .animate({ width: "0px"}, 500)
                       .hide()
                       .end()
                       .hide(); 
               });
          select.fadeTo("slow", 0.01, function() { 
                  select.parent()
                       .animate({ width: "0px"}, 500)
                       .hide()
                       .end()
                       .hide(); 
               });
      }
    });

});
Russ Cam
That's pretty much what I want. What's with the ".hide().end().hide()"?
Shea Daniels
at the start of the chain, the wrapped set is moved to the parent element of the original wrapped set. That element is hidden first, then the end() command reverts back to the original wrapped set and then that element is hidden.
Russ Cam
I would imagine that considering this hides the <td> elements too that the animate() command could have any other animation substituted for it. I just chose that one as it looked smoother to collapse horizontally
Russ Cam
I like the slide of the button, I just wish that I could get the elements that are being hidden to fade out nicely instead of blink out of existence. It seems like if I change any particular piece about your code then it stops working, which is a little frustrating. The other thing is that I can't seem make the the drop down reappear using show().
Shea Daniels
take a look at this - http://jsbin.com/ucora . add /edit if you want to see the code. IIRC, you can't fade a <select> in IE (might just be IE6, can't remember).
Russ Cam
That's great. I had some ideas brewing about using callbacks to do the second animation, and it looks like that's what you've done. If you want to edit your answer with the new code I'll choose it.
Shea Daniels