javascript expand/collapse button - javascript
I'm trying to create a toggle content button that loads with the content already hidden.
This is the code I'm using but I'm not sure how to make the content appear as hidden (making the toggle button function more used for expanding content)
$(function() {
var b = $("#button");
var w = $("#wrapper");
var l = $("#list");
w.height(l.outerHeight(true));
b.click(function() {
if(w.hasClass('open')) {
w.removeClass('open');
w.height(0);
} else {
w.addClass('open');
w.height(l.outerHeight(true));
}
});
});
#wrapper {
background: #ccc;
overflow: hidden;
transition: height 200ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Toggle Expand/Collapse</button>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
Option 1: Simplified Code
You can actually simplify a fair amount by relying on CSS to define the show/hide style, and transitioning on max-height, you then simply toggle the addition of e.g. an open class to allow the height of the content to expand.
This also maintains strict separation of concerns, keeping functionality withiin Javascript and styling within CSS.
$(function() {
var b = $("#button");
var w = $("#wrapper");
var l = $("#list");
b.click(function() {
w.toggleClass('open'); /* <-- toggle the application of the open class on click */
});
});
#wrapper {
background: #ccc;
overflow: hidden;
transition: max-height 300ms;
max-height: 0; /* <---hide by default */
}
#wrapper.open {
max-height: 100px; /* <---when open, allow content to expand to take up as much height as it needs, up to e.g. 100px */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Toggle Expand/Collapse</button>
<div id="wrapper">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
Option 2: Revised Code
Alternatively, if you wish to use your existing code, you need to change it so the default state is hidden. Do this by setting the height to zero in your CSS, removing the open class from your HTML and removing the initial height setting from your Javascript:
$(function() {
var b = $("#button");
var w = $("#wrapper");
var l = $("#list");
// w.height(l.outerHeight(true)); REMOVE THIS
b.click(function() {
if (w.hasClass('open')) {
w.removeClass('open');
w.height(0);
} else {
w.addClass('open');
w.height(l.outerHeight(true));
}
});
});
#wrapper {
background: #ccc;
overflow: hidden;
transition: height 200ms;
height: 0; /* <-- set this */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Toggle Expand/Collapse</button>
<!-- <div id="wrapper" class="open"> REMOVE THIS -->
<div id="wrapper">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
you can use jquery .toggle() method
<button id="button">Toggle Expand/Collapse</button>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
$('#button').click(function(){
$('#wrapper').toggle();
});
DEMO
updated
you can add the following .css
#wrapper {
background: #ccc;
display:none
}
DEMO
jQuert toggle method will help you, if you want it hidden for the first time apply style like this -> style="display:none" If you want it visible then don't add this style
Basically what toggle function does is, if your component visible then hides it and if it is hidden then shows it...
$('#button').click(function(){
$('#wrapper').toggle();
})
below code will explain you better
http://jsfiddle.net/31zfvm2u/
using CSS
You can accomplish this with just CSS:
div#wrapper {
transition: max-height 1000ms;
overflow: hidden;
}
#toggle:not(:checked) ~ div#wrapper {
max-height: 0;
}
#toggle:checked ~ div#wrapper {
max-height: 200px;
}
#toggle:checked ~ label:after {
content: "hide"
}
#toggle:not(checked) ~ label:after {
content: "show"
}
<input type="checkbox" id="toggle">
<label for="toggle"></label>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
using JavaScript
You're pretty much there. Just use $.hide and $.show instead of $.height.
A more succinct method would be $.toggle, however, which does the same as the below code.
$(function() {
var b = $("#button");
var w = $("#wrapper");
var l = $("#list");
w.height(l.outerHeight(true));
b.click(function() {
if(w.hasClass("open")) {
w.hide();
} else {
w.show()
}
w.toggleClass("open");
});
});
#wrapper {
background: #ccc;
overflow: hidden;
transition: height 200ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Toggle Expand/Collapse</button>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
<button id="button" onclick=sample();>Toggle Expand/Collapse</button>
<div id="wrapper" class="open">
<ul id="list">
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>
function sample()
{
$(#wrapper).toogle();
}
Related
How to make a scrollable dropdown menu in bootstrap 5? [duplicate]
This question already has answers here: Scrollable Menu with Bootstrap - Menu expanding its container when it should not (6 answers) Closed 1 year ago. I've seen some great code examples for dropdown menus you can scroll through but sadly most don't work with bootstrap 5. Is there any modern way to do this?
Do you mean a fixed height for the menu? HTML: <div class="container"> <div class="dropdown"> <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Click on Me <span class="caret"></span></button> <ul class="dropdown-menu"> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> </ul> </div> </div> CSS: .dropdown-menu { max-height: 100px; overflow-y: scroll; }
You can try below css for scrollable dropdown. Here You can set max-height: 100vh which limits it to 100% of the viewport's height. So, It will show in any viewport nicely. Don't forget to minus header height from calc(100vh - 150px). 150px is the height of the header on my site example. You can replace as per your site. which is above the height of the dropdown. .dropdown-menu { overflow: hidden; overflow-y: auto; max-height: calc(100vh - 150px); }
How to Create Accordion Menu Footer For Mobile Only
How can I create a footer that collapses on mobile and you have to click on the Menu Title to actually expand ? I want the footer menu to look normally on the desktop , something like this : and 2. for mobile to look like this , basically to collapse automatically and the user having the option to expand or close the menu Thank you ! My current code : <div class="three columns" > <h2 > Legal </h2> <ul> <li> Shipping</li> <li> <a href="#" >Contact Us</a></li> <li> About</li> <li> Returns</li> </ul> </div> <div class="three columns" > <h2> Information </h2> <ul> <li> Privacy</li> <li> <a href="#" >Terms</a></li> <li> Ambassadors</li> <li> Blog</li> </ul> </div>
I hope this can help you. jQuery(".nav-footer h4").click(function(){ jQuery(this).parent(".nav").toggleClass("open"); }); .nav-footer-item ul { list-style: none; padding-left: 3px; } .open h4 { opacity: 0.3; } h4 { font-size: 30px; } .nav-footer-item { padding: 25px !important; } #media (max-width : 768px) { .nav-footer .nav h4 { cursor: pointer; } .nav-footer ul { max-height: 0; overflow:hidden; transition: max-height 1s ease-out; } .nav-footer .nav h4:after { content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='svg-icon' viewBox='0 0 20 20'%3E%3Cpath d='M14.613,10c0,0.23-0.188,0.419-0.419,0.419H10.42v3.774c0,0.23-0.189,0.42-0.42,0.42s-0.419-0.189-0.419-0.42v-3.774H5.806c-0.23,0-0.419-0.189-0.419-0.419s0.189-0.419,0.419-0.419h3.775V5.806c0-0.23,0.189-0.419,0.419-0.419s0.42,0.189,0.42,0.419v3.775h3.774C14.425,9.581,14.613,9.77,14.613,10 M17.969,10c0,4.401-3.567,7.969-7.969,7.969c-4.402,0-7.969-3.567-7.969-7.969c0-4.402,3.567-7.969,7.969-7.969C14.401,2.031,17.969,5.598,17.969,10 M17.13,10c0-3.932-3.198-7.13-7.13-7.13S2.87,6.068,2.87,10c0,3.933,3.198,7.13,7.13,7.13S17.13,13.933,17.13,10'%3E%3C/path%3E%3C/svg%3E"); width: 25px; float: right; } .nav-footer .nav.open h4:after { content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='svg-icon' viewBox='0 0 20 20'%3E%3Cpath d='M10.185,1.417c-4.741,0-8.583,3.842-8.583,8.583c0,4.74,3.842,8.582,8.583,8.582S18.768,14.74,18.768,10C18.768,5.259,14.926,1.417,10.185,1.417 M10.185,17.68c-4.235,0-7.679-3.445-7.679-7.68c0-4.235,3.444-7.679,7.679-7.679S17.864,5.765,17.864,10C17.864,14.234,14.42,17.68,10.185,17.68 M10.824,10l2.842-2.844c0.178-0.176,0.178-0.46,0-0.637c-0.177-0.178-0.461-0.178-0.637,0l-2.844,2.841L7.341,6.52c-0.176-0.178-0.46-0.178-0.637,0c-0.178,0.176-0.178,0.461,0,0.637L9.546,10l-2.841,2.844c-0.178,0.176-0.178,0.461,0,0.637c0.178,0.178,0.459,0.178,0.637,0l2.844-2.841l2.844,2.841c0.178,0.178,0.459,0.178,0.637,0c0.178-0.176,0.178-0.461,0-0.637L10.824,10z'%3E%3C/path%3E%3C/svg%3E"); width: 25px; } .nav-footer .nav.open ul { height:auto; max-height: 500px; transition: max-height 1s ease-in !important; } } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> <script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> <footer class="nav-footer"> <div class="nav-footer-item nav col-sm-3"> <h4>Title</h4> <ul> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> </ul> </div> <div class="nav-footer-item nav col-sm-3"> <h4>Title</h4> <ul> <li>Item</li> <li>Item</li> <li>Item</li> </ul> </div> <div class="nav-footer-item nav col-sm-3"> <h4>Title</h4> <ul> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> </ul> </div> <div class="nav-footer-item nav col-sm-3"> <h4>Title</h4> <ul> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> </ul> </div> </footer>
I suggest you not go with JS approach since there's a good alternative with CSS which gives you the same behavior and logic. Look at this example https://www.w3schools.com/howto/howto_css_switch.asp
Unexpected width in shopify draggable element
I made a simple draggable list, using the shopify draggable plugin <ul id="myList"> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> <li>Item</li> </ul> ul { width: 50%; border: 1px solid black; list-style: none; margin: 0; padding: 0; } li { margin: 5px; background: salmon; width: calc(100% - 10px); cursor: move; } For some reason, when dragging, the dragged item's width gets much greater than the original item's. I suspect it's because I set the width in percentages and that it gets taken out of the parent container, so the percentage reference changes. I made a jsfiddle demo: https://jsfiddle.net/x3jmkysq/1/ I would like it to work more like this example: https://shopify.github.io/draggable/examples/simple-list.html but I don't know how exactly they achieved it.
Anyway, I found the solution here: https://github.com/Shopify/draggable/issues/147 Basically there is a property to calculate the dimensions of the dragged element from the original one called constrainDimensions.
Equal Width Tab Items Generated Dynamically
I am creating tabs that needs to be equal in width, it will come dynamically (2-8 tabs). There is no fixed width, tab bar has fluid width. I had tried to achieve it through css, but didn't worked. demo:http://codepen.io/anon/pen/JdbMwR <div class="main"> <ul class="list-inline sub-cat-tabs"> <li> <div> <span>2014-2015 2014-2015</span> </div> </li> <li> <div> <span>2015-2015</span> </div> </li> </ul> </div>
You could do it with CSS fixed table layout, browser support: IE8+ http://jsfiddle.net/gashvbp6/ .tabs { list-style: none; padding: 0; margin: 0; display: table; border-collapse: collapse; table-layout: fixed; width: 100%; } .tabs li { display: table-cell; text-align: center; vertical-align: middle; border: 1px solid red; } <ul class="tabs"> <li>item - long one</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> </ul>
Making a drop-down menu scrollable
I am trying to implement a drop down menu in a HTML page using CSS and jquery. Here is a sample of the HTML and javascript code. <nav id="topNav"> <ul> <li>Menu 1</li> <li> Menu 2 <ul> <li>Sub Nav Link 1</li> <li>Sub Nav Link 2</li> <li>Sub Nav Link 3</li> <li>Sub Nav Link 4</li> <li class="last">Sub Nav Link 5</li> </ul> </li> <li> Menu 3 </li> </ul> </nav> Here is the Javascript code: var nav = $("#topNav"); //add indicators and hovers to submenu parents nav.find("li").each(function() { if ($(this).find("ul").length > 0) { $("<span>").text("^").appendTo($(this).children(":first")); //show subnav on hover $(this).click(function() { $(this).find("ul").stop(true, true).slideToggle(); }); } }); I will be adding content to menu programmatically, and I want the dropdown menus to be scrollable when the content of the dropdown menu gets too large. How can I do this?
Try this using css like, #topNav ul li ul{ max-height:250px;/* you can change as you need it */ overflow:auto;/* to get scroll */ } Demo
There is a css property max-height you can use it: #topNav ul ul{ max-height:150px; // you choice of number in pixels overflow-x:hidden; // hides the horizontal scroll overflow-y:auto; // enables the vertical scroll }
Why not use a purely CSS solution? FIDDLE You can change the transition property to have the style of animation for the slide you prefer, and the max-height value to limit the size of the dropdown before scrolling occurs. HTML <ul id='menu'> <li>item</li> <li>item</li> <li>dropdown <ul> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> <li>item</li> </ul> </li> </ul> CSS body, html { width:100%; } ul { list-style:none; margin:0; padding:0 } #menu > li { display:inline-block; border:1px solid grey; position:relative; } #menu li ul { position:absolute; border:1px solid grey; width:100%; max-height:0; overflow:hidden; -moz-transition: 1s; -ms-transition: 1s; -o-transition: 1s; -webkit-transition: 1s; transition: 1s; } #menu li:hover ul { overflow:auto; max-height:50px; }
use CSS style: #topNav{ overflow:scroll; }
Isn't it possible to set a height and then overflow: auto, as CSS a property? and the scroll will automatically appear?