Toggle sidebar: expand/collapse

Looking for some assistance with my website project. I currently have two arrows to open and close the sidebar, but I would like one button to handle both actions instead. Can someone help me edit my code snippet to achieve this? Keep in mind that I am new to JavaScript and still learning. Thanks in advance!

This is the current code for the arrows:

function openNav() {
  document.getElementById("sidenav").style.width = "250px";
}

function closeNav() {
  document.getElementById("sidenav").style.width = "0";
}
// CSS styles go here
<!DOCTYPE html>
<html>

<head>
  <title>Video CMS</title>
  <link rel="stylesheet" type="text/css" href="css/style.css">
  <script src="js/sidebar.js"></script>
</head>

<body>
  <div class="header">
    <div class="search"></div>
  </div>
  <div class="toggle">
    <div class="group-buttons"></div>
    <span class="close-button" onclick="closeNav()">&#8592;</span>
    <span class="close-button" onclick="openNav()">&#8594;</span>
  </div>
  <div id="sidenav" class="sidenav">
    <div class="uploadvideo">
      <div class="upload-btn-wrapper">
        <button class="btn">Upload Video</button>
        <input type="file" name="myfile" />
      </div>
    </div>
    <div class="thumbnail"></div>
    <div class="thumbnail"></div>
    <div class="thumbnail"></div>
    <div class="thumbnail"></div>
  </div>
</body>

</html>

Answer №1

To hide the open button, simply add display:none:

.sidebar-button {
  line-height: 70px; 
  color: #eee; 
  font-size: 25px; 
  margin-left: 20px;
  cursor:pointer
}

.sidebar-button:hover {
     color: #b9b9b9;
}

/** The open button isn't visible by default, since the sidebar is already open **/

#open-button {
  display:none;
}

Then, adjust which button has display:none and display:block based on whether the sidebar is open or closed:

function openNav() {
  document.getElementById("sidenav").style.width = "250px";
  document.getElementById("close-button").style.display = "block";
  document.getElementById("open-button").style.display = "none";
}

function closeNav() {
  document.getElementById("sidenav").style.width = "0";
  document.getElementById("close-button").style.display = "none";
  document.getElementById("open-button").style.display = "block";
}

You may also want to add user-select: none; to the buttons to prevent them from being selected as text.

Full code snippet:

function openNav() {
  document.getElementById("sidenav").style.width = "250px";
  document.getElementById("close-button").style.display = "block";
  document.getElementById("open-button").style.display = "none";
}

function closeNav() {
  document.getElementById("sidenav").style.width = "0";
  document.getElementById("close-button").style.display = "none";
  document.getElementById("open-button").style.display = "block";
}
body {
  background-color: #fcfcfc;
  font-family: Roboto, Arial, sans-serif;
}

.sidebar-button {
  line-height: 70px;
  color: #eee;
  font-size: 25px;
  margin-left: 20px;
  cursor: pointer;
  user-select: none;
}

.sidebar-button:hover {
  color: #b9b9b9;
}


/** The open button isn't visible by default, since the sidebar is already open **/ 

#open-button {
  display: none;
}

.header {
  width: 100%;
  height: 70px;
  top: 0;
  left: 0;
  position: fixed;
  background-color: #fff;
  border-bottom: 1px solid #eee;
}

.toggle {
  width: 250px;
  height: 70px;
  border-right: 1px solid #eee;
  position: fixed;
  top: 0;
  left: 0;
}

.sidenav {
  height: 100%;
  width: 250px;
  top: 0;
  left: 0;
  position: fixed;
  z-index: 1;
  overflow-x: hidden;
  transition: 0.3s;
  margin-top: 71px;
  background-color: #fff;
  border-right: 1px solid #eee;
  line-height: 80px;
  overflow: hidden;
}

.sidebar-videos {
  font-size: 18px;
  text-align: center;
}

.uploadvideo {
  color: #707070;
  text-align: center;
  text-transform: uppercase;
  font-size: 14px;
  width: 250px;
  height: 80px;
  border-bottom: 1px solid #eee;
  margin-bottom: 10px;
}

.thumbnail {
  border: 1px solid #eee;
  height: 120px;
  width: 200px;
  margin-left: 22px;
  cursor: pointer;
  margin-bottom: 15px;
}

.thumbnail:hover {
  border: 1px solid #b9b9b9;
}

.upload-btn-wrapper {
  position: relative;
  overflow: hidden;
  display: inline-block;
}

.btn {
  cursor: pointer;
  border: 1px solid #eee;
  background-color: #8BC34A;
  padding: 13px 15px;
  color: #fff;
}

.upload-btn-wrapper input[type=file] {
  font-size: 100px;
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
}

.search {
  float: right;
  width: 250px;
  height: 70px;
  border-left: 1px solid #eee;
}
<!DOCTYPE html>
<html>

<head>
  <title>Video CMS</title>
  <link rel="stylesheet" type="text/css" href="css/style.css">
  <script src="js/sidebar.js"></script>
</head>

<body>
  <div class="header">

    <div class="search"></div>
  </div>
  <div class="toggle">
    <div class="group-buttons"></div>
    <span class="sidebar-button" id="close-button" onclick="closeNav()">&#8592;</span>
    <span class="sidebar-button" id="open-button" onclick="openNav()">&#8594;</span>
  </div>
  <div id="sidenav" class="sidenav">
    <div class="uploadvideo">
      <div class="upload-btn-wrapper">
        <button class="btn">Video Uploaden</button>
        <input type="file" name="myfile" />
      </div>
    </div>
    <div class=thumbnail"></div>
    <div class="thumbnail"></div>
    <div class="thumbnail"></div>
    <div class="thumbnail"></div>
  </div>
</body>

</html>

Answer №2

If you're looking for a solution, you might consider implementing the following code snippet:

function toggleNav() {
    console.log(document.getElementById("sidenav").style.width)
    if (document.getElementById("sidenav").style.width == '0px') {
        document.getElementById("sidenav").style.width = "250px";
    } else {
       document.getElementById("sidenav").style.width = '0px'
    }
}
body {
  background-color: #fcfcfc;
  font-family: Roboto, Arial, sans-serif;
}

.header {
  width: 100%;
  height: 70px;
  top: 0;
  left: 0;
  position: fixed;
  background-color: #fff;
  border-bottom: 1px solid #eee;

}

.toggle {
     width: 250px;
     height: 70px;
     border-right: 1px solid #eee;
     position: fixed;
     top: 0;
     left: 0;
}

.sidenav {
    height: 100%;
    width: 250px;
    top: 0;
    left: 0;
    position: fixed;
    z-index: 1;
    overflow-x: hidden;
    transition: 0.3s;
    margin-top: 71px;
    background-color: #fff;
    border-right: 1px solid #eee;
    line-height: 80px;
    overflow: hidden;
}


.close-button {
  line-height: 70px; 
  color: #eee; 
  font-size: 25px; 
  margin-left: 20px;
  cursor:pointer
}

.close-button:hover {
     color: #b9b9b9;
}

.sidebar-videos {
    font-size: 18px;
  text-align: center;
}

.uploadvideo {
  color: #707070;
  text-align: center;
  text-transform: uppercase;
  font-size: 14px;
  width: 250px;
  height: 80px;
  border-bottom: 1px solid #eee;
  margin-bottom: 10px;
}

.thumbnail {
  border: 1px solid #eee;
  height: 120px;
  width: 200px;
  margin-left: 22px;
  cursor: pointer;
  margin-bottom: 15px;
}

.thumbnail:hover {
  border: 1px solid #b9b9b9;
}

.upload-btn-wrapper {
  position: relative;
  overflow: hidden;
  display: inline-block;
}

.btn {
  cursor: pointer;
  border: 1px solid #eee;
  background-color: #8BC34A;
  padding: 13px 15px;
  color: #fff;
}

.upload-btn-wrapper input[type=file] {
  font-size: 100px;
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
}

.search {
  float: right;
  width: 250px;
  height: 70px;
  border-left: 1px solid #eee;
}
<!DOCTYPE html>
<html>
<head>
<title>Video CMS</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="js/sidebar.js"></script>
</head>
<body>
 <div class="header">

 <div class="search"></div>
 </div>
 <div class="toggle">
 <div class="group-buttons"></div>
 <span class="close-button" onclick="toggleNav()">&#8592;</span>
</div>
 <div id="sidenav" class="sidenav">
 <div class="uploadvideo">
 <div class="upload-btn-wrapper">
  <button class="btn">Upload Video</button>
  <input type="file" name="myfile" />
</div>
 </div>
 <div class="thumbnail"></div>
 <div class="thumbnail"></div>
 <div class="thumbnail"></div>
 <div class="thumbnail"></div>
 </div>
</body>
</html>

Answer №3

Using just one button and a toggle, achieving the desired result is simple.

function toggleNav() {
  var isClose = document.getElementById("sidenav").style.width === "0px";
  document.getElementById("sidenav").style.width = isClose ? "250px" : "0px";
  document.getElementById("close-button").innerHTML = isClose ? "←" : "→";
}
body {
  background-color: #fcfcfc;
  font-family: Roboto, Arial, sans-serif;
}
... (CSS code continues)
<!DOCTYPE html>
<html>

<head>
  <title>Video CMS</title>
  <link rel="stylesheet" type="text/css" href="css/style.css">
  <script src="js/sidebar.js"></script>
</head>
... (HTML code continues)

Answer №4

Below are the modifications I made to your code snippet:

  • Established a variable that tracks whether the sidebar is toggled
  • Implemented a toggle function that opens or closes the sidebar based on the navToggled variable
  • Updated CSS classes to toggle-button and toggle-button:hover
  • Replaced the icon in the top left corner with a trigram symbol
var navToggled = false;

function toggleNav() {
  if (navToggled) {
    openNav();
    navToggled = false;
  } else {
    closeNav();
    navToggled = true;
  }
}

function openNav() {
  document.getElementById("sidenav").style.width = "250px";
}

function closeNav() {
  document.getElementById("sidenav").style.width = "0";
}
body {
  background-color: #fcfcfc;
  font-family: Roboto, Arial, sans-serif;
}

.header {
  width: 100%;
  height: 70px;
  top: 0;
  left: 0;
  position: fixed;
  background-color: #fff;
  border-bottom: 1px solid #eee;
}

.toggle {
  width: 250px;
  height: 70px;
  border-right: 1px solid #eee;
  position: fixed;
  top: 0;
  left: 0;
}

.sidenav {
  height: 100%;
  width: 250px;
  top: 0;
  left: 0;
  position: fixed;
  z-index: 1;
  overflow-x: hidden;
  transition: 0.3s;
  margin-top: 71px;
  background-color: #fff;
  border-right: 1px solid #eee;
  line-height: 80px;
  overflow: hidden;
}

.toggle-button {
  line-height: 70px;
  color: #eee;
  font-size: 35px;
  margin-left: 20px;
  cursor: pointer
}

.toggle-button:hover {
  color: #b9b9b9;
}

.sidebar-videos {
  font-size: 18px;
  text-align: center;
}

.uploadvideo {
  color: #707070;
  text-align: center;
  text-transform: uppercase;
  font-size: 14px;
  width: 250px;
  height: 80px;
  border-bottom: 1px solid #eee;
  margin-bottom: 10px;
}

.thumbnail {
  border: 1px solid #eee;
  height: 120px;
  width: 200px;
  margin-left: 22px;
  cursor: pointer;
  margin-bottom: 15px;
}

.thumbnail:hover {
  border: 1px solid #b9b9b9;
}

.upload-btn-wrapper {
  position: relative;
  overflow: hidden;
  display: inline-block;
}

.btn {
  cursor: pointer;
  border: 1px solid #eee;
  background-color: #8BC34A;
  padding: 13px 15px;
  color: #fff;
}

.upload-btn-wrapper input[type=file] {
  font-size: 100px;
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
}

.search {
  float: right;
  width: 250px;
  height: 70px;
  border-left: 1px solid #eee;
}
<!DOCTYPE html>
<html>

<head>
  <title>Video CMS</title>
  <link rel="stylesheet" type="text/css" href="css/style.css">
  <script src="js/sidebar.js"></script>
</head>

<body>
  <div class="header">
    <div class="search"></div>
  </div>
  <div class="toggle">
    <div class="group-buttons"></div>
    <span class="toggle-button" onclick="toggleNav()">&#x2630;</span>
  </div>
  <div id="sidenav" class="sidenav">
    <div class="uploadvideo">
      <div class="upload-btn-wrapper">
        <button class="btn">Upload Video</button>
        <input type="file" name="myfile" />
      </div>
    </div>
    <div class="thumbnail"></div>
    <div class="thumbnail"></div>
    <div class="thumbnail"></div>
    <div class="thumbnail"></div>
  </div>
</body>

</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combining objects in JavaScript

I am currently working on converting the object received from the server into a format compatible with the backend system. I have a received object that looks like this { 'User.permissions.user.view.dashboard': true, 'Admin.permissio ...

Switch between light and dark mode on a webpage using HTML

I am looking to create a script using JavaScript, HTML, and CSS that can toggle between dark mode and night mode. Unfortunately, I am unsure of how to proceed with this task. https://i.sstatic.net/xA3Gq.png https://i.sstatic.net/v5vq5.png My goal is to ...

Troubleshooting date format errors when parsing two parameters in a jQuery AJAX request

Does anyone have advice on how to make an ajax call with two parameters - number and date? I encountered the following error: Warning: date_format() expects parameter 1 to be DateTimeInterface, boolean given in... Here is the HTML code involved: <di ...

Exclusive pair of vertices within a network

I am working with a diagram that includes nodes A, B, C and several edges connecting these nodes. How can I extract the distinct pairs (A, B), (A, C), (B, C)? One potential method is: visited = []; for item1 in nodes: for item2 in nodes: if (item ...

Currently in the process of developing an electron application, I encountered an Uncaught Exception error stating: "TypeError: $.ajax is not

I'm currently working on an electron app that interacts with an API endpoint and displays the response on the page. Due to electron's separation of main process and renderer process, I'm using a preload script to facilitate communication bet ...

Troubles with the compatibility of javascript and jquery's multiselect plugin

I've been utilizing the multiselect API to create a dropdown with multiple select options. This is my HTML code: <select id="options" multiple="multiple"></select> And this is my JS code: render:function(){ // $('#viewTemp& ...

Fluid Design - Extra Spacing at the Bottom with Percent Margin-Top

Currently, I am working on developing a website using only percentages. However, I have encountered an issue with my main content section. I have set a margin-top of 10%, but this is causing excessive spacing at the bottom of the page and resulting in a sc ...

How to Share Your Vuejs Component with the World by Publishing it on npm

I have recently developed a Vue.js 2 project using webpack which consists of 2 components. My goal is to share this project as an npm package so that the components can be easily reused in multiple projects. After publishing the project on npm with npm pu ...

How can async/await help in retrieving the value of a CORS request?

Trying to make a CORS request and utilize async/await to extract the value from it (using jquery). The functions createCORSRequest and executeCORSRequest seem to be functioning correctly, so the implementation details are not my main concern. The function ...

I am attempting to incorporate an NPM package as a plugin in my Next.js application in order to prevent the occurrence of a "Module not found: Can't resolve 'child_process'" error

While I have developed nuxt apps in the past, I am new to next.js apps. In my current next.js project, I am encountering difficulties with implementing 'google-auth-library' within a component. Below is the code snippet for the troublesome compon ...

Angular Component - Array missing initial value in @Input property

Having trouble transferring values between components? I'm currently dealing with a situation involving two components: report-form and comment-form. The report form contains an array of comments, displaying a list of comments and a button for each on ...

How can you automate the execution of unit tests in Angular before pushing changes to Git?

There have been instances in Angular projects where the unit tests are triggered every time a build is carried out, as well as when running the git push command. In case any tests fail during either of these commands, the process halts until all unit tes ...

Struggling with Selenium as I attempt to click multiple "Remove" buttons, constantly encountering the StaleElementReferenceException error

I am facing a challenge when trying to remove multiple elements on a webpage. My current approach involves locating all the "Remove" buttons and clicking them one by one. However, I keep encountering a 'StaleElementReferenceException' as I remove ...

Add an element to the jQuery collection before the last element, not at the end

My challenge lies in utilizing AJAX to post a comment. However, the last comment element features a submit button within it. Consequently, whenever a new item is appended, it appears after the submit button. <div class="commentContainer" > < ...

HTML and CSS styled accordion with nested checkboxes: handling long items

I am currently working on creating a multi-level accordion for an aside navigation section on a webpage. However, I have encountered an issue where the background color extends too far when hovering over a specific element. This occurs on a folder-type ite ...

"Encountering a strange behavior in Vue.js: the created() hook

I made a custom feature to refresh my data from the database by clicking a button: <template> <base-projects :projects="projects" /> </template> <script> import { mapGetters } from 'vuex'; import Projects from './ ...

Issues with the alignment of card-footer in Bootstrap 5 card components

Looking to enhance the website for the electronics store I am employed at, I have encountered a challenge while constructing cards using Bootstrap 5. Initially, the cards varied in height until I managed to resolve the issue by setting the card height to 1 ...

How can I implement the self-clearing feature of a timer using clearInterval in ReactJS?

I am a newcomer to the world of React and I am currently working on creating a React component with multiple features. Users can input a random number, which will then be displayed on the page. The component includes a button labeled 'start'. W ...

Switching from using jQuery to Mootools in a short script that helps to balance the heights of

I have a simple script that I frequently use in jQuery to make boxes equal heights. Now, I need to convert it to mootools for a new project where the boxes will be floated left at thirds using style sheets. <div id="box1" class="equals">content he ...

Show every item from a collection on individual lines within an Angular2 module

I am working with an Angular2 component that is responsible for displaying a list of speakers stored in some data. Currently, when I add the code below to my xyz.component.html, it shows the list as comma-separated strings. However, I would like each speak ...