views:

57

answers:

2

In trying to build a page where I can filter the types of jobs and the offices using the hide/show function, I find that if an element is hidden, then an element underneath the element is "told" to hide, it doesn't actually hide. In other words, hide only works if the actual element is shown.

Here is the code, to duplicate, Hide office 2, then hide developers, then show office 2 again. The developers (which "should" be hidden) display within office 2.

Is there a way around this? It would seem jquery would hide the "sub" elements as well, but it doesn't.

<input  type="checkbox" id=office1 name="test"  class="link1" />Office 1<BR>
<input  type="checkbox" name="office2"  checked='true' class="link2"/>Office 2<BR>
<input  type="checkbox" name="office3"  checked='true' class="link3" />Office 3<BR>
<input  type="checkbox" name="developer"  checked='true' class="link4" />Developer<BR>
<input  type="checkbox" name="receptionist"   checked='true' class="link5" />Receptionist<BR>
<input  type="checkbox" name="manager"   checked='true' class="link6" />Manager<BR>
<table border='1'>
    <tr>
        <td class="toggle-item-link1"><B>Office 1</B><HR>
        <div class="toggle-item-link6"><BR>Manager</div>
        <div class="toggle-item-link6"><BR>Manager</div>
        <div class="toggle-item-link6"><BR>Manager</div>
        </td>
    </tr>
    <tr >
        <td class="toggle-item-link2"><B>Office 2</B><HR>
        <div class="toggle-item-link4"><BR>Developer</div>
        <div class="toggle-item-link4"><BR>Developer</div>
        <div class="toggle-item-link6"><BR>Developer</div>
        <div class="toggle-item-link5"><BR>Receptionist</div>
        </td>
    </tr>
    <tr>
        <td class="toggle-item-link3"><B>Office 3</B><HR>
        <div class="toggle-item-link4"><BR>Developer</div>
        <div class="toggle-item-link4"><BR>Developer</div>
        <div class="toggle-item-link5"><BR>Receptionist</div>
        </td>
    </tr>

        <td>
        </td>
    </tr>
</table>
<script>
$(document).ready(function() {

    $('[class^=link]').click(function() {
        if ($(this).attr("checked")) {
            var $this = $(this);
            var x = $this.attr("className");
            //when 'checked'

            $('.toggle-item-' + x).show(1000);

            return;
        }
        //when 'unchecked'
        var $this = $(this);
        var x = $this.attr("className");

        $('.toggle-item-' + x).hide(1000);
    });

});
</script>
+1  A: 

In addition to the hide()/show(), use a class named hidden, with the CSS:

.hidden {
  display: none;
}

When you hide the item, you also add the class hidden. And when you show it, you also remove hidden.

Gert G
Ok, that works, except I have to remove the transition speed from 1000 to null or put the add/remove Class before the hide/show commands. The problem is, if I don't, then the space still shows where the missing developers are. (To duplicate this, I find I had to do it a couple times, which seems to me I might be missing something, if this is confusing, I can submit code)Otherwise, the main objective is met, I just lose the transition effect. Thanks
There's no need to put it to zero. Just add/remove the class in a callback function (`show(1000,callback)`/`hide(1000,callback)`). That way the class is added/removed after the show/hide has been executed.
Gert G
@Gert G: The problem is that `hide()` won't run for already hidden elements, so the callback won't run either, also removing the class in the show callback means it would instantly appear after a second :)
Nick Craver
@Nick Craver - Good points. You probably need loop through the targetted elements and checking if they're displayed or not, and then take different actions on them.
Gert G
@Gert G: There's actually a very simple solution below, check my answer :)
Nick Craver
@Nick Craver - I'll delete my answer once the checkmark has been transfered to your answer.
Gert G
+2  A: 

Since .hide() with an animation speed will only run on visible elements, you can add a case in there for hidden ones as well, like this (a few more optimizations here, just cutting down on code):

$('[class^=link]').click(function()  {
    var x =  $(this).attr("className");
    if (this.checked) {
        $('.toggle-item-'  + x).show(1000);
    } else {
        $('.toggle-item-'  + x).hide(1000).filter(':hidden').hide();
    }
});

You can try out a demo here. We're just accounting for the already :hidden elements that won't animate and skipping to them doing a display: none; by calling .hide() without an animation speed.

Nick Craver
ok, read your answer second. That fixed the problem in my latest comment. Thanks... I'll have to read up on the filter command.
@user401214: Welcome :) be sure to accept answers on this and future questions via the check-mark beside the one that resolved it :)
Nick Craver
@user401214 - Yes, mark Nick's answer as the accepted answer. It's way easier than mine... and it works nicely.
Gert G