jQuery - vertical up toggle (i.e. not down)
Asked Answered
R

4

9

I need to create a toggle that animates upwards not downwards in other words the reverse of the "normal" toggle. Perhaps simpler is the toggle should slide up above the menu item (it's a menu) to become visible rather than slide down as the normal slideToggle etc. would do. I am nearly there with this :

var opened = false;
$("#coltab li").click(function(){
    if(opened){
        $(this).children('ul').animate({"top": "+=300px"});
    } else {
        $(this).children('ul').animate({"top": "-=300px"});
    }
    $(this).children('ul').children().slideToggle('slow');
    $(this).children('ul').toggle();
    opened = opened ? false : true;
});

BUT if you "toggle" an item THEN another item the second item (slides down) falls by the 300px NOT slide up (raises) by 300px. A good example (hate the site) of what I want to achieve is http://market.weogeo.com/#/home and the "tabs"at the bottom.

My HTML code is using

<ul id="#coltab">
<li>Item 1
<ul>
<li>This bit needs to toggle up</li>
</ul>
</li>
<li>Item 2
<ul>
<li>This bit needs to toggle up</li>
</ul>
</li>
etc ...
</ul>

On the CSS side

ul#coltab { position: relative' blah; blah; }

and

ul#coltab  ul { display: none; position: absolute; blah; blah; }

Any ideas?

It would be nice if each "click" closed the previous toggle before opening the "clicked" toggle.

Retired answered 1/1, 2011 at 15:24 Comment(3)
Here's my edit version of the ones posted below :D jsfiddle.net/s7AD8/2Baroja
@Cristy Ohhh I hate you :-) that is "right" and much what I have "created" but I get it to work just using slideToggle - no need for the animate - unless I am missing something?Retired
Yeah, no need for animate, I've just used that because the example posted below used it :))Baroja
P
3

I could give a more specific answer if you would have provided the actual CSS for your lists instead of filler.

Basically, you'll want to set the bottom property of ul#coltab ul to 0.

Generic example: http://jsfiddle.net/s7AD8/

ul#coltab  ul {
    position:absolute;
    bottom:0;
    /*...and so on*/
}

This will cause it to animate in an upward direction.

Philip answered 1/1, 2011 at 15:36 Comment(11)
@patrick dw - oops sorry about that position is absolute; bottom: 0px;Retired
@Russell: That should work. I added a generic example to demonstrate the upward animation. If yours doesn't do that with bottom:0, then you'll need to provide the code necessary to reproduce the issue.Philip
@patrick dw - thanks "been there" I thinks it might be the fact that it is in ul's but here is the code anyhow: <ul id="coltab" class="clearfix"><li>Features<ul><li class="test">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sed neque eu est consequat scelerisque sit amet ac orci.</li></ul></li><li>Blog<ul><li class="test">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </li></ul></li></ul>ul#coltab ul { display: none; position: absolute; z-index: 998; margin: 0px; bottom: 0px; padding: 0px; list-style: none; }Retired
@patrick dw - continued ... ul#coltab li ul li.test { position: relative; line-height: normal;} it;s not that the toggle "up" doesn't work it's more if you toggle "twice" i.e. with a toggled item already open then the JQuery "reverses" the codeRetired
@patrick dw just had a "closer" look, your jsfiddle.net/s7AD8 example does go up BUT I need the "menu item" to be at the bottom. i.e. the yellow should show at the bottom not the top after the toggleRetired
Got to it before me (ofc) but I made my own, as proof of concept. :) jsfiddle.net/66YCvCamarilla
@Russell: The yellow is the background, and the red is the menu. Here's an updated example reducing the width of the menu. jsfiddle.net/s7AD8/1 Perhaps use jsFiddle to create a working example of your code.Philip
@patrick dw & @Meke - ummm . got it now thanks to both, it is the UL's making the problem. If I use Meke's example with a few additions from patricks code it works fine. will finish off the code then post it here. But PLEASE PLEASE tell me how best to "reward you both" as I can only accept 1 answer, but you have both given me "bits" to the solution.Retired
OK just voted you both up 1 but still need to know how to rewardRetired
Don't worry, just hand the answer to whoever provided the most information. :) (Hint: It's patrick) ((Later on you can vote up comments too btw)Camarilla
@Meke - very generous of you; like that not too often we "give away praise" Hope you have some good "paying" customers - cos you should have with that "nice" attitude.Retired
M
3

Try this one:

$("#coltab li ul").each(function (index) {
  $(this).data('height', $(this).outerHeight());    
});

$("#coltab li").click(function () {

    $("#coltab li ul.open").animate({"top": 0}, function () {
        $(this).removeClass('open');  
    });

    var itemHeight = $(this).children('ul').data('height');
    $(this).find('ul:not(.open)').animate({"top": -itemHeight}).addClass('open');

});

And add a new css class:

#coltab ul.open { display: block; }

Test it here

Myel answered 1/1, 2011 at 16:6 Comment(2)
I have seen .data(''); before but not sure what it is, but from your example I can guess it calcs the height of the "content" or data but even if css display none?Retired
Have a look at the documentation: api.jquery.com/jQuery.data - "Store arbitrary data associated with the specified element." | So this code snippet is storing the original height of the items which need to be toggled, in order to animate to the appropriate top position later.Myel
C
1

"-=300px" would feel better being a precalculated var.. (Can you even handle calculations in strings?)

Further if you wish to manipulated them independently I'd imagine you'll have a much easier time by providing IDs for the parts you want to handle

Camarilla answered 1/1, 2011 at 15:31 Comment(3)
yes +/-=300px would be better as precalculated var, BUT as the UL is display none till toggled it has no height so you (OK I can't do) height(); to pre-calculate it If that can be done - generally - would love to know and learn. Thks for commentRetired
"Can you even handle calculations in strings?" Yes, jQuery lets you do this in animations.Philip
@Patrick: I see... That does give me some new options in my project ^^ ThanksCamarilla
B
1

You can also use a different way if you need to free up ul and li for something else:

<style>
body { margin: 100px 50px; }

#coltab { position: relative; text-align: center; }

#coltab > li {
    background: #ccc;
    color: #444;
    cursor: pointer;
    display: block;
    float: left;
    margin: 0 10px;
    padding: 10px 20px;
    position: relative;
    width: 100px;
}

#coltab span {
    background: #eee;
    color: #222;
    display: none;
    padding: 5px;
    position: absolute;
    left: 0;
    right; 0;
    top: 0;
    z-index: -1;
}

#coltab span.open { display: block; }

</style>

<head>

<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js"> </script>

</head>

<body>



<div id="coltab">
    <li>Item 1<br/>(click me)
            <span>This first item needs to toggle up</span>
    </li>
    <li>Item 2<br/>(click me)
            <span>This second item needs to toggle up</span>
    </li>
</div>

<script>
$(document).ready(function() {
$("#coltab li span").each(function (index) {
  $(this).data('height', $(this).outerHeight());    
});

$("#coltab li").click(function () {

    $("#coltab li span.open").animate({"top": 0}, function () {
        $(this).removeClass('open');  
    });

    var itemHeight = $(this).children('span').data('height');
    $(this).find('span:not(.open)').animate({"top": -itemHeight}).addClass('open');

});
});
</script>
</body>
Breastplate answered 3/3, 2011 at 23:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.