Search code examples
javascriptjquerymaterializesidenav

Materialize fixed-sidebar close


I have a Materialize fixed sidenav which is visible all time. I want to add button which will open and close it.

If I add $('.sidenav').sidenav('close') to the button it can only close the sidebar; similarly with $('.sidenav').sidenav('open').

I do not want make two buttons. How can I solve this?

This is function which intializes the sidebar:

$(document).ready(function () {
  $('.sidenav').sidenav();
});

Here's my HTML:

<ul id="slide-out" class="sidenav sidenav-fixed">
  <li>
    <div class="user-view">
      <div class="background">
        <img src="img/flag.png">
      </div>
      <a href="#user"><img class="circle" src="img/yuna.jpg"></a>
      <a href="#name"><span class="white-text name">John Doe</span></a>
      <a href="#email"><span class="white-text email">[email protected]</span></a>
    </div>
  </li>
  <div class="nav-wrapper">
    <form>
      <div class="input-field">
        <input id="search" type="search" required>
        <label class="label-icon" for="search"><i class="material-icons">search</i></label>
        <i class="material-icons">close</i>
      </div>
    </form>
  </div>
  <li><a href="#!"><i class="material-icons">account_balance</i>Departments</a></li>
  <li><a href="#!"><i class="material-icons">store</i>Regions</a></li>
  <li><a href="#!"><i class="material-icons">description</i>Districts</a></li>
  <li><a href="#!"><i class="material-icons">panorama</i>Cities</a></li>
  <li><a href="#!"><i class="material-icons">time_to_leave</i>Vehicles</a></li>
  <li><div class="divider"></div></li>
  <li><a class="subheader">Subheader</a></li>
  <li><a class="waves-effect" href="#!">Third Link With Waves</a></li>
  <li><a class="sidenav-close" href="#!">Clicking this will close Sidenav</a></li>
</ul>

I have a button with class .sidenav-close which is not working (it is default). I think it is because my sidebar is fixed.

Are there any default methods to open and close it?

This is my button which needs to open/close it:

<a href="#!" data-target="slide-out" class="sidenav-trigger rb_nav_btn">
  <i class="material-icons">menu</i>
</a>

I thought about writing a function which will check if the sidebar is open then close it on click and the other way round.


Solution

  • The fixed navbar is not meant to be closed... Its only meaning is to provide a fast way to implement an always visible navbar. So what you're asking is basically to have a simple navbar open right after initialized... The only difference between the simple and the fixed navbar is that the latter starts open.

    Btw, as you thought you could use the property instance.isOpen as said in the Docs to check if the sidenav is open. If yes close it, else open it. I used the floating button and commented the default trigger for the sidenav since its function is replaced by the floating button.

    NOTE: In order to see it in action you need to Run the code snippet and click the FULL PAGE link, otherwise you won't see the navbar and you'll have to open it manually. This because looking at the code seems that Sidenav closes itself if the width of the window is < 992:

    Source: materialize.js (line 5834)

    value: function _handleWindowResize() {
      // Only handle horizontal resizes
      if (this.lastWindowWidth !== window.innerWidth) {
        if (window.innerWidth > 992) {
          this.open();
        } else {
          this.close();
        }
      }
    
      this.lastWindowWidth = window.innerWidth;
      this.lastWindowHeight = window.innerHeight;
    }
    

    Here is your script:

    document.addEventListener("DOMContentLoaded", function() {
      var elems = document.querySelectorAll(".sidenav");
      var options = {};
      var instances = M.Sidenav.init(elems, options);
    
      document
        .querySelector("#toggle_sidenav")
        .addEventListener("click", function() {
          var elem = document.querySelector(".sidenav");
          var instance = M.Sidenav.getInstance(elem);
    
          if (instance.isOpen) {
            console.log("Is open: I need to close it");
            instance.close();
          } else {
            console.log("Is closed: I need to open it");
            instance.open();
          }
        });
    });
    header, main, footer {
      padding-left: 300px;
    }
    
    @media only screen and (max-width: 992px) {
      header,  main, footer {
        padding-left: 0;
      }
    }
    <!-- Compiled and minified CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
    
    <!-- Compiled and minified JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    
    <!--Import Google Icon Font-->
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    
    <ul id="slide-out" class="sidenav sidenav-fixed">
      <li><a href="#!">First Sidebar Link</a></li>
      <li><a href="#!">Second Sidebar Link</a></li>
    </ul>
    <!-- <a href="#" data-target="slide-out" class="sidenav-trigger"><i class="material-icons">menu</i></a> -->
    
    <div style='position: absolute; bottom:10px; right:10px'>
      <a id="toggle_sidenav" class="btn-floating btn-large waves-effect waves-light red"><i class="material-icons">add</i></a>
    </div>