HTML/JavaScript: Sidebar expand/collapse button - javascript

So I'm using this "Color Admin Responsive Admin Template" (http://wrapbootstrap.com/preview/WB0N89JMK) and I have a sidebar menu, and I have the expand/collapse button displaying, but the actual function is not working. I'm not sure exactly why it isn't working, I got the function from the template. I'm pretty new to JavaScript but I think everything that I needed to change on my specific HTML matches the function.
HTML
<!--sidebar left start-->
<!-- begin #sidebar -->
<div id="sidebar" class="sidebar">
<!-- begin sidebar scrollbar -->
<div data-scrollbar="true" data-height="100%">
<!-- begin sidebar user -->
<ul class="nav">
<li class="nav-profile">
<div class="info">
Matt Smith
<small>Manager</small>
</div>
</li>
</ul>
<!-- end sidebar user -->
<ul class="nav">
<!-- begin sidebar minify button -->
<li><i class="fa fa-angle-double-left"></i></li>
<!-- end sidebar minify button -->
</ul>
</div>
<!-- end sidebar scrollbar -->
</div>
<!--sidebar left end-->
JavaScript
var handleSidebarMinify = function() {
$('[data-click=sidebar-minify]').click(function(e) {
e.preventDefault();
var sidebarClass = 'page-sidebar-minified';
var targetContainer = '#page-container';
if ($(targetContainer).hasClass(sidebarClass)) {
$(targetContainer).removeClass(sidebarClass);
if ($(targetContainer).hasClass('page-sidebar-fixed')) {
generateSlimScroll($('#sidebar [data-scrollbar="true"]'));
}
} else {
$(targetContainer).addClass(sidebarClass);
if ($(targetContainer).hasClass('page-sidebar-fixed')) {
$('#sidebar [data-scrollbar="true"]').slimScroll({destroy: true});
$('#sidebar [data-scrollbar="true"]').removeAttr('style');
}
// firefox bugfix
$('#sidebar [data-scrollbar=true]').trigger('mouseover');
}
$(window).trigger('resize');
});
};
http://jsfiddle.net/BootstrapOrBust/71og00ev/1/

You do not include jQuery library in your html. I've added check for JQuery at the top of your code:
alert(typeof jQuery !== "undefined")
it returns false that means you don't add JQuery. You can see the Uncaught ReferenceError: $ is not defined error on browser console. Updated JSFiddle

You can do this (without an animation) without any javascript at all, using the css's :hover.
EDIT: I just realised you wanted to control the expansion and collapse with buttons. This answer doesn't address that, but I'll leave it here anyway as an alternative.
JSFiddle: http://jsfiddle.net/2byg62z4/
<style>
body { margin: 0; }
#sidepanel
{
position: absolute;
min-width: 30px;
height: 60%;
top: 20%;
left: 0;
}
#bar
{
display: table;
background-color: #999999;
color: white;
width: 30px;
height: 100%;
text-align: center;
}
#bar div
{
display: table-cell;
vertical-align: middle;
}
#panel
{
display: none;
background-color: #999999;
color: white;
width: 300px;
height: 100%;
text-align: center;
}
#panel div
{
display: table-cell;
vertical-align: middle;
}
#sidepanel:hover #bar { display: none; }
#sidepanel:hover #panel { display: table; }
</style>
<div id='sidepanel'>
<div id='bar'>
<div>
><br>><br>>
</div>
</div>
<div id='panel'>
<div>
stuff
</div>
</div>
</div>

Related

HTML & CSS: triggering active class for a section in index.html

So normally when I visit for ex "index.html" and I give my a href link in my navbar the class "active" or whatever class and colour it so it defines which page I'm on
so
<a href="index.html" class="active">
and
a.active {
background-color: #009879;
color: white;
}
would just do the trick and highlights the page I'm currently on in the navbar
but I have a section in my index.html which I can go to by clicking on this in the navbar
<a href="index.html#about">
but if I trigger the class="active" for this section, then both the index and the section will be highlighted in my navbar
how do I make it so that when I'm on the section, my index.html loses its class=active and for the section to gain that class?
possibly if this could be done using only CSS!
TL;DR I need a way in CSS/JS that adds/removes the class for whatever element(s) I want it to be on.
Hi, The function you want in your project is called scrollspy and it is achieved with javascript. You can use the bootstrap or create the function in pure javascript. But in order not to reinvent the wheel I show you an example based on a vanilla javascript script from: https://github.com/cferdinandi/gumshoe.
var spy = new Gumshoe('#my-awesome-nav a');
html {
overflow-y: auto;
scroll-behavior: smooth;
}
/* Sets body width */
.container {
max-width: 90em;
width: 88%;
margin-left: auto;
margin-right: auto;
}
/**
* Grid
*/
.grid {
display: grid;
grid-gap: 2em;
grid-template-columns: 30% 70%;
}
#my-awesome-nav {
position: fixed;
}
#my-awesome-nav li.active {
background-color: black;
}
#my-awesome-nav li.active a {
color: white;
}
/**
* Sections
*/
.section {
color: #ffffff;
height: 95vh;
margin: 0;
padding: 2em;
}
#eenie {
background-color: #0088cc;
}
#meenie {
background-color: rebeccapurple;
}
#miney {
background-color: #272727;
}
#mo {
background-color: #f42b37;
}
<script src="https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe/dist/gumshoe.polyfills.min.js"></script>
<div class="container">
<div class="grid">
<nav>
<ul id="my-awesome-nav">
<li>Eenie</li>
<li>Meenie</li>
<li>Miney</li>
<li>Mo</li>
</ul>
</nav>
<main>
<div class="section" id="eenie">
Eenie...
</div>
<div class="section" id="meenie">
Meenie...
</div>
<div class="section" id="miney">
Miney...
</div>
<div class="section" id="mo">
Mo...
</div>
<p><a data-scroll href="#top">Back to the top</a></p>
</main>
</div>
</div>

Keep getting "cannot read property style of null" error

I am working on my own website and not good with codes yet. When I am scrolling down I want to appear another content of the navbar and when I am on the top, original navbar is appearing. I want this to be done in pure JavaScript with no libraries or framewokrs. Please see codes below and I know that codes are not organised. I will do that later on.
var nav = document.querySelector("nav");
var hide = document.querySelector(".hide");
var appear = document.querySelector(".appear")
window.onscroll = function(){
if(document.body.scrollTop > 70){
hide.style.display = "block";
appear.style.display = "none"
} else {
hide.style.display = "none";
appear.style.display = "block"
}
}
nav{
list-style-type: none;
text-align: center;
background-color: #3FA9A5;
position: sticky;
top: 0;
}
.hide{
font-size: 70px;
font-family: 'Long Cang', cursive;
display: block;
}
.appear{
height: 70px;
display: none;
}
.appear img{
width: 210px;
}
ul{
margin: 0 auto;
padding: 0;
}
body{
margin: 0;
}
.container{
max-width: 1080px;
width: 95%;
margin: 10px auto;
display: grid;
grid-template-columns: 25% 50% 25%;
}
.text{
text-align: center;
}
.profile {
border: 1px solid black;
padding: 0 10px 20px 10px;
}
#main{
width: 100%;
}
.post{
margin-left: 4.165%;
}
#image{
width: 100%;
}
#post-divide{
margin-left: 10px;
margin-right: 10px;
}
.comments{
width: 100%;
margin-top: 68.5px;
padding-bottom: 293.5px;
border: 1px solid black;
}
h2{
text-align: center;
}
.center{
grid-column: 2;
}
<link rel="stylesheet" type="text/css" href="test.css">
<link href="https://fonts.googleapis.com/css?family=Indie+Flower|Long+Cang&display=swap" rel="stylesheet">
<title>test</title>
</head>
<body>
<nav>
<ul>
<li class="hide">Unknown</li>
<li class="appear"><img src="cat.png"></li>
</ul>
</nav>
<div class="container">
<div class="col-1">
<div class="profile text">
<img id="main" src="https://data.whicdn.com/images/86629641/superthumb.jpg?t=1384568664">
<hr>
<p>12 posts</p>
<p>instagram</p>
<button>Subscribe!</button>
</div>
</div>
<div class="col-1">
<div class="post">
<h2>TITLE</h2>
<div>
<img id="image" src="https://i.pinimg.com/originals/76/d4/8c/76d48cb2928845dfcfab697ac7cbcf1c.jpg">
</div>
<hr id="post-divide">
</div>
</div>
<div class="col-1">
<div class="comments text"></div>
</div>
<div class="col-1 center">
<div class="post">
<h2>TITLE</h2>
<div>
<img id="image" src="https://i.pinimg.com/originals/76/d4/8c/76d48cb2928845dfcfab697ac7cbcf1c.jpg">
</div>
<hr id="post-divide">
</div>
</div>
<div class="col-1">
<div class="comments text"></div>
</div>
</div>
I think I should add something to the JS code but don't know why
Would be thankful if you would advise me how could I write HTML/CSS code so I do not have to create 2 navbars if it is possible
The following instruction:
document.querySelector("hide");
Will query for elements like:
<hide></hide>
Since plain selectors without prefix (div, header, span) will query for the whole element tags, not for classes or attrbitues.
Maybe you meant to query for the class, using the .:
document.querySelector(".hide");
var hide = document.querySelector(".hide");
var appear = document.querySelector(".appear")
So you should use class selector
You are using "hide" and "appear" as selectors but they do not exist in your HTML.
Use ".hide" and ".appear" in your querySelector instead.
var hide = document.querySelector(".hide");
var appear = document.querySelector(".appear");
Since both navbars have a static data, I would suggest to keep both of them and follow with answers of guys, that suggested to update querySelector param. Or you can hide/show the data inside of navbar (in your case it's only ul element) and leave the whole navbar always visible. So you can put classes appear/hide on ul element instea of navbar and then in JS get them with document.querySelector('.navbar .hide') and document.querySelector('.navbar .appear').
Using framework/library will definitely simplify it.
However, if you still want to have only one navbar in pure js/html/css (or it's data just dynamic) I would probably do like this:
HTML:
<nav class="navbar">
<ul>
<li><img src="cat.png"></li>
</ul>
</nav>
somewhere in JS:
var navbarUl = document.querySelector('.navbar ul');
window.onscroll = function() {
if (document.body.scrollTop > 70) {
navbarUl.innerHtml = '';
navbarUl.appendChild(getTopNavbarHTML);
} else {
navbarUl.innerHtml = '';
navbarUl.appendChild(getNavbarHTML);
}
}
getNavbarHTML and getTopNavbarHTML - will return documentFragment with li elements, see for details https://www.w3schools.com/jsref/met_document_createdocumentfragment.asp
But changing DOM during a scroll event can drastically decrease performance of a web app

How to remove whitespace and grey box outside of HTML body

I have an app with a Leaflet.js map and a sidebar. On the desktop, it appears to look fine, but when I run page inspector and select a mobile version, there is whitespace at the bottom of the page(outside of the map/sidebar), along with an odd grey box.
I cannot inspect either the whitespace or the grey box when I mouseover them with the pointer. I have tried changing the body CSS to no avail (including no bottom margin/padding for the body).
I am a bit mystified here. Here's the basic HTML structure:
<body>
<!-- links to scripts go here -->
<!-- Content Starts here -->
<div class="wrapper">
<!-- Sidebar -->
<nav id="sidebar">
<div class="sidebar-header">
<div class="filterContainer">
<!-- filter map data with radio buttons here -->
</div>
<div class="filterContainer">
<!-- filter map data with radio buttons here -->
</div>
</div>
<!-- filter map data with calendar -->
<div id="datepicker"></div>
</nav>
<!-- Page Content -->
<div id="content">
<!-- map -->
<div id="map" style="min-width: 100vh; min-height: 100vh">
<button type="button" id="sidebarCollapse" class="btn btn-info">
<span>Filter Events</span>
</button>
</div>
</div>
</div>
<script>
</script>
And, some of the relevant CSS:
body {
font-family: 'Poppins', sans-serif;
background: #fafafa;
height:100%;
max-height:100%;
overflow: hidden;
padding-bottom: 1px;
}
.wrapper {
display: flex;
width: 100%;
align-items: stretch;
}
#sidebar {
min-width: 250px;
max-width: 250px;
}
.filterContainer ul{
list-style: none;
margin: 0;
margin-top: -12%;
margin-left: -12%;
}
#content{
width:100%;
height:100%;
}
#map{
height:100%;
}
And, finally, an image of the problem:

scroll to next and previous tab from tabbed box

I've build a tab Container with multiple Tabs and corresponding content, which is only visible if the corresponding Tab is clicked. This works great so far, but I have tried to add two buttons which will navigate to the next and previous tab and I don't know how to achieve this.
You'll find below what I've done so far. I think it's no so good JS code, maybe someone can give me also some hint's to improve it.
Thanks in advance for your help
$(document).ready(function(){
// hide all contents accept from the first div
$('.tabContent div:not(:first)').toggle();
// hide the previous button
$('.previous').hide();
$('.tabs li').click(function () {
if($(this).is(':last-child')){
$('.next').hide();
}else{
$('.next').show();
}
if($(this).is(':first-child')){
$('.previous').hide();
}else{
$('.previous').show();
}
var position = $(this).position();
var corresponding = $(this).data("id");
// scroll to clicked tab with a little gap left to show previous tabs
scroll = $('.tabs').scrollLeft();
$('.tabs').animate({'scrollLeft': scroll+position.left-30},200);
// hide all content divs
$('.tabContent div').hide();
// show content of corresponding tab
$('div.' + corresponding).toggle();
// remove active class from currently not active tabs
$('.tabs li').removeClass('active');
// add active class to clicked tab
$(this).addClass('active');
});
});
body{
background-color: gray;
}
*{
box-sizing: border-box;
}
.contentWrapper{
width: 350px;
margin: 0 auto;
position: relative;
}
.tabsWrapper{
width: 100%;
height: 24px;
overflow: hidden;
position: relative;
}
.tabs{
margin: 0;
padding: 0;
position: absolute;
top: 0;
bottom: -25px;
left: 0;
right: 0;
white-space: nowrap;
overflow: auto;
}
.tabs li{
display: inline-block;
background-color: #ccc;
padding: 3px 8px;
cursor: pointer;
}
.tabs li.active{
background-color: white;
}
.next, .previous{
position: absolute;
padding: 2px 4px;
top: 0;
background-color: white;
}
.next{
right: -25px;
}
.previous{
left: -25px;
}
.tabContent{
width: 100%;
background-color: white;
padding: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="contentWrapper">
<div class="tabsWrapper">
<ul class="tabs">
<li data-id="contentOne" class="active">CSS</li>
<li data-id="contentTwo">HTML, HTML, HTML</li>
<li data-id="contentThree">JS and jQuery</li>
<li data-id="contentFour">one more tab</li>
<li data-id="contentFive">another tab</li>
<li data-id="contentSix">the last tab</li>
</ul>
</div>
<a class="next">></a>
<a class="previous"><</a>
<div class="tabContent">
<div class="contentOne">
<p>this is the CSS tab Content</p>
next
</div>
<div class="contentTwo">
<p>this is the HTML tab Content<br><br>1</p>
next
</div>
<div class="contentThree">
<p>this is the JS tab Content</p>
next
</div>
<div class="contentFour">
<p>this is the sample Content</p>
next
</div>
<div class="contentFive">
<p>this is more sample Content</p>
next
</div>
<div class="contentSix">
<p>this is more than more sample Content</p>
next
</div>
</div>
</div>
You can use trigger('click') to programmatically click the tab you want. This way all the code written for tab change will automatically get executed. For example see the following code:
$('div a').click(function(e){
e.preventDefault();
$('li.active').next('li').trigger('click');
});
See JsFiddle here

Jquery toggleclass in separate divs

I'm using the js from bootstrap to do a div collapse on a Wordpress gallery page but I can't get the toggle function to work. When you click on another item, the first item doesn't collapse. It stays open. You can see it the link to the dev site: Dev site link
I'm not using the accordion bootstrap setup as I wanted each collapsing div to occupy the same space below the row of triggering links.
I've asked this question from a bootstrap point of view but got no answers. So I'm wondering if there's a way of doing it using Jquery toggleclass?
Bootstrap applies the class 'in' to the expanded item. So I guess I'd need to have toggle class remove that? I found and tried to adapt some Jquery but no luck.
A simplified version of the code is:
<div id="desktop-view">
<div id="gallery-squares-1" class="gallery-squares clearfix">
<a href="#collapseExample-1" class="ie-bgsize gallery-img" data-toggle="collapse" data-parent="#desktop-view">
<div class="img-mouse-over"></div>
</a><!-- .post-gallery-img -->
<a href="#collapseExample-2" class="ie-bgsize gallery-img" data-toggle="collapse" data-parent="#desktop-view">
<div class="img-mouse-over"></div>
</a><!-- .post-gallery-img -->
<a href="#collapseExample-3" class="ie-bgsize gallery-img" data-toggle="collapse" data-parent="#desktop-view">
<div class="img-mouse-over"></div>
</a><!-- .post-gallery-img -->
</div> <!-- .gallery-squares -->
<div id="gallery-expanders-1" class="gallery-expanders clearfix">
<div class="collapse" id="collapseExample-1">
<div class="gallery-content">
<div class="ie-bgsize gallery-content-img"></div>
<h6>Title</h6>
<p>Description</p>
</div> <!-- .gallery-content -->
</div> <!-- .collapse -->
<div class="collapse" id="collapseExample-2">
<div class="gallery-content">
<div class="ie-bgsize gallery-content-img"></div>
<h6>Title</h6>
<p>Description</p>
</div> <!-- .gallery-content -->
</div> <!-- .collapse -->
<div class="collapse" id="collapseExample-3">
<div class="gallery-content">
<div class="ie-bgsize gallery-content-img"></div>
<h6>Title</h6>
<p>Description</p>
</div> <!-- .gallery-content -->
</div> <!-- .collapse -->
</div> <!-- .gallery-expanders -->
</div>
CSS:
a.gallery-img {
width: 15%;
padding-bottom: 15%;
margin: 0 1.6666666% 1.6666666% 0;
display: block;
float: left;
position: relative;
background-color: #fff;
}
.gallery-content {
background-color: black;
margin-bottom: 1.6666666%;
color: #fff;
padding: 1.6666666%;
}
.gallery-content-img {
width: 98.5%;
padding-bottom: 50%;
margin-bottom: 1.8%;
}
.gallery-content h6 {
color: #fff;
font-size: 18px;
line-height: 1.2em;
margin: 0;
width: 98.5%;
}
.gallery-content p {
font-size: 14px;
line-height: 1.2em;
margin: 1% 0;
width: 98.5%;
}
.gallery-content p:last-child {
margin-bottom: 0;
}
.img-mouse-over {
width: 100%;
height: 100%;
margin: 0;
position: absolute;
background: none;
}
.img-mouse-over:hover,
.img-mouse-over:active {
background: rgba(0, 0, 0, 0.5) no-repeat center center;
}
JQuery I tried:
$('.gallery-squares a').click(function(e){
e.preventDefault();
$('.collapse').removeClass('in');
});
I just can't get it to remove the active class on 'in'. I guess I'd also need to make sure it only removed the 'in' from the current active div and not the one that the click will create?
Thanks in advance for any advice.
you'll have to remove the in class and add the collapse class.
$(document).on('show.bs.collapse', function () {
$('.in').addClass('collapse').removeClass('in');
})
Okay, so if we never want the in class there...
$(document).on('shown.bs.collapse', function () {
$('.in').removeClass('in');
})
or possibly on the 'show event:
$(document).on('show.bs.collapse', function () {
$('.in').removeClass('in');
})
(I'm not sure which one since I don't know when it adds the class in)
See the docs for the collapse events here

Categories

Resources