LiveWithPassion
LiveWithPassion

Reputation: 527

Sidebar navigation toggle with single button

I have implemented the following sidebar navigation into a simple admin. I've got it working and moved to the right side. I would like to have it appear and disappear using a single button rather than a separate close and open button. I tried modifying the JS with an onToggle function that if isOpen was null, it would open the panel and then set isOpen to true and then the next time it ran, it would delete isOpen. I'm very new at JS and this failed so I thought I'd ask here. How do I get this puppy appearing and disappearing with a single button?

http://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_sidenav

Thank you kindly.

Upvotes: 1

Views: 12153

Answers (3)

hulkinBrain
hulkinBrain

Reputation: 746

<!DOCTYPE html>
<html>
<style>
body {
    font-family: "Lato", sans-serif;
}

.sidenav {
    height: 100%;
    width: 0;
    position: fixed;
    z-index: 1;
    top: 60px;
    left: 0;
    background-color: #111;
    overflow-x: hidden;
    transition: 0.5s;
    padding-top: 60px;
}

.sidenav a {
    padding: 8px 8px 8px 32px;
    text-decoration: none;
    font-size: 25px;
    color: #818181;
    display: block;
    transition: 0.3s
}

.sidenav a:hover, .offcanvas a:focus{
    color: #f1f1f1;
}

.closebtn {
    position: absolute;
    top: 0;
    right: 25px;
    font-size: 36px !important;
    margin-left: 50px;
}

@media screen and (max-height: 450px) {
  .sidenav {padding-top: 15px;}
  .sidenav a {font-size: 18px;}
}
</style>
<body>
<span style="font-size:30px;cursor:pointer" onclick="openNav()">☰ open</span>
<div id="mySidenav" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">×</a>
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

<h2>Animated Sidenav Example</h2>
<p>Click on the element below to open the side navigation menu.</p>


<script>
function openNav() {
    var e = document.getElementById("mySidenav");
    if (e.style.width == '250px')
    {
        e.style.width = '0px';
    }
    else 
    {
        e.style.width = '250px';
    }
}

function closeNav() {
    document.getElementById("mySidenav").style.width = "0";
}
</script>

</body>
</html> 

This is the same code with little modifications in the openNav() method. For triggering the sideNavbar with a button, it needs to be visible before and after triggering the sideNavBar. So i have moved the view button to the top and i have modified the top property of sidenav to keep the trigger button visible even after activation

You can view this in action here: https://jsfiddle.net/ngohrvk1/

Upvotes: 3

Praveen Puglia
Praveen Puglia

Reputation: 5631

I know the question is tagged with JavaScript and you probably don't want to change the markup or add new elements. But if you could, here's a pure CSS solution that works.

body {
  margin: 0;
}
.sidebar-toggle {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  padding: 10px;
  background: red;
  color: white;
}
#sidebar-toggle-input {
  display: none;
}
#sidebar-toggle-input+label:before {
  content: "➡️";
}
#sidebar-toggle-input:checked + label:before {
  content: "❌"
}
.sidebar {
  position: fixed;
  width: 200px;
  transition: 0.3s;
  background: blue;
  height: 100vh;
  top: 0;
  left: 0;
  transform: translateX(-100%);
}
#sidebar-toggle-input:checked ~ .sidebar {
  transform: none;
}
<input type="checkbox" id="sidebar-toggle-input" />
<label class="sidebar-toggle" for="sidebar-toggle-input"></label>
<div class="sidebar"></div>

Upvotes: 2

Parag Bhayani
Parag Bhayani

Reputation: 3330

This code will help you out, I have created a function and saving data-isshown attribute on the element, to get whether the element is shown or not, we can decide this on the basis of the width as well but this is more generic approach

function toggleNav() {
  var element = document.getElementById("mySidenav")
  var shown = element.getAttribute("data-isshown");
  if (shown == "true") {
    element.setAttribute("data-isshown", "false");
    element.style.width = "0";

  } else {
    element.setAttribute("data-isshown", "true");
    element.style.width = "250px";
  }
}

Whole code would look like this

function toggleNav() {
  var element = document.getElementById("mySidenav")
  var shown = element.getAttribute("data-isshown");
  if (shown == "true") {
    element.setAttribute("data-isshown", "false");
    element.style.width = "0";

  } else {
    element.setAttribute("data-isshown", "true");
    element.style.width = "250px";
  }
}
body {
  font-family: "Lato", sans-serif;
}
.sidenav {
  height: 100%;
  width: 0;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  background-color: #111;
  overflow-x: hidden;
  transition: 0.5s;
  padding-top: 60px;
}
.sidenav a {
  padding: 8px 8px 8px 32px;
  text-decoration: none;
  font-size: 25px;
  color: #818181;
  display: block;
  transition: 0.3s
}
.sidenav a:hover,
.offcanvas a:focus {
  color: #f1f1f1;
}
.closebtn {
  position: absolute;
  top: 0;
  right: 25px;
  font-size: 36px !important;
  margin-left: 50px;
}
@media screen and (max-height: 450px) {
  .sidenav {
    padding-top: 15px;
  }
  .sidenav a {
    font-size: 18px;
  }
}
<div id="mySidenav" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="toggleNav()">×</a>
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

<h2>Animated Sidenav Example</h2>
<p>Click on the element below to open the side navigation menu.</p>
<span style="font-size:30px;cursor:pointer" onclick="toggleNav()">☰ open</span>

Upvotes: 1

Related Questions