Home > front end >  Collapsible vertical sidebar menu icon with submenu
Collapsible vertical sidebar menu icon with submenu

Time:01-03

A collapsible sidebar menu, where I'm looking for a plus ( ) sign to toggle to a minus (-) sign. When the sidebar menu opens and toggles the same operation happened again.

From the documentation and community code resource, I'm able to toggle the collapse menu, but I'm looking for a right-side plus ( ) icon also changed from a plus ( ) to a minus(-) icon

I used bootstrap icons and for the plus and dash signs following classes are used respectively <i ></i> , <i ></i>

;
(function() {
  document.addEventListener("DOMContentLoaded", function() {

    document.querySelectorAll('.g-sidebar .nav-link').forEach(function(element) {

      element.addEventListener('click', function(e) {

        let nextEl = element.nextElementSibling;
        let parentEl = element.parentElement;

        if (nextEl) {
          e.preventDefault();
          let sidebarNavCollapse = new bootstrap.Collapse(nextEl);

          if (nextEl.classList.contains('show')) {
            sidebarNavCollapse.hide();
          } else {
            sidebarNavCollapse.show();
            // find other submenus with class=show
            let opened_submenu = parentEl.parentElement.querySelector('.submenu.show');
            // if it exists, then close all of them
            if (opened_submenu) {
              new bootstrap.Collapse(opened_submenu);
            }

          }
        }

      });
    })

  });
})();
.g-aside {
  background-color: #8c8c8c;
  width: 260px;
}

.nav {
  --bs-nav-link-padding-x: 1rem;
  --bs-nav-link-padding-y: 0.5rem;
  --bs-nav-link-color: var(--bs-link-color);
  --bs-nav-link-hover-color: var(--bs-link-hover-color);
  --bs-nav-link-disabled-color: #6c757d;
  display: flex;
  flex-wrap: wrap;
  padding-left: 0;
  margin-bottom: 0;
  list-style: none;
}

.submenu>li {
  list-style: none;
}

.g-sidebar .nav-link {
  position: relative;
  display: flex;
  font-family: quicksand, sans-serif;
  color: #fff;
  width: calc(260px - 1rem);
  transition: width .3s ease-in-out;
  list-style: none!;
}

.g-sidebar .nav-link p {
  margin-bottom: 0;
  padding-left: 1.4rem;
  display: inline-block;
}

.g-sidebar .nav-link p i,
.g-sidebar .nav-link p span {
  right: 1rem;
  position: absolute;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<aside >
  <!--Sidebar Area-->
  <div >
    <nav >
      <ul  id="nav_accordion">

        <li >
          <a  href="#">
            <i ></i>
            <p>Agents</p>
          </a>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>Dashboard <i ></i></p>
          </a>
          <ul >

            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>IVR <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>Page <span >12</span></p>
          </a>
        </li>
        <!--                    <li >PROMOTION</li>-->
        <li >
          <a  href="#">
            <i ></i>
            <p>Campaign <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>Report <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>New Report <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p> Skill </p>
          </a>
        </li>

        <li >
          <a  href="#">
            <i ></i>
            <p>Voice Mail </p>
          </a>
        </li>
        <li >
          <a  href="#"><i ></i>
                            <p>Chat <i ></i></p></a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#"><i ></i>
                            <p>Email <i ></i></p></a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#"><i ></i>
                            <p>SMS <i ></i></p></a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>


        <li >
          <a  href="#">
            <i ></i>
            <p>CRM <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>CRM Inbound <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
      </ul>
    </nav>
  </div>
</aside>

CodePudding user response:

Try querying for bi-plus and if that doesn't work query bi-dash and flag self. Then you can remove all dashes and replace with plus, and depending on flag add plus or dash

;
(function() {
  document.addEventListener("DOMContentLoaded", function() {

    document.querySelectorAll('.g-sidebar .nav-link').forEach(function(element) {

      element.addEventListener('click', function(e) {
        let self=false

        let nextEl = element.nextElementSibling;
        let parentEl = element.parentElement;
        let childImg = element.querySelector('.bi-plus');
        if(!childImg){
            self = true;
            childImg = element.querySelector('.bi-dash');
        }

        if (nextEl) {
          e.preventDefault();
          let sidebarNavCollapse = new bootstrap.Collapse(nextEl);

          if (nextEl.classList.contains('show')) {
            sidebarNavCollapse.hide();
          } else {
            document.querySelectorAll('.nav-link .bi-dash').forEach(function(elem){
              if (elem!==childImg) {
                elem.classList.add('bi-plus')
                elem.classList.remove('bi-dash')
              }
            })
            if(!self){
              childImg.classList.remove('bi-plus')
              childImg.classList.add('bi-dash')
            } else {
              childImg.classList.remove('bi-dash')
              childImg.classList.add('bi-plus')
            }
            sidebarNavCollapse.show();
            // find other submenus with class=show
            let opened_submenu = parentEl.parentElement.querySelector('.submenu.show');
            // if it exists, then close all of them
            if (opened_submenu) {
              new bootstrap.Collapse(opened_submenu);
            }

          }
        }

      });
    })

  });
})();
.g-aside {
  background-color: #8c8c8c;
  width: 260px;
}

.nav {
  --bs-nav-link-padding-x: 1rem;
  --bs-nav-link-padding-y: 0.5rem;
  --bs-nav-link-color: var(--bs-link-color);
  --bs-nav-link-hover-color: var(--bs-link-hover-color);
  --bs-nav-link-disabled-color: #6c757d;
  display: flex;
  flex-wrap: wrap;
  padding-left: 0;
  margin-bottom: 0;
  list-style: none;
}

.submenu>li {
  list-style: none;
}

.g-sidebar .nav-link {
  position: relative;
  display: flex;
  font-family: quicksand, sans-serif;
  color: #fff;
  width: calc(260px - 1rem);
  transition: width .3s ease-in-out;
  list-style: none!;
}

.g-sidebar .nav-link p {
  margin-bottom: 0;
  padding-left: 1.4rem;
  display: inline-block;
}

.g-sidebar .nav-link p i,
.g-sidebar .nav-link p span {
  right: 1rem;
  position: absolute;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
<aside >
  <!--Sidebar Area-->
  <div >
    <nav >
      <ul  id="nav_accordion">

        <li >
          <a  href="#">
            <i ></i>
            <p>Agents</p>
          </a>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>Dashboard <i ></i></p>
          </a>
          <ul >

            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>IVR <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>Page <span >12</span></p>
          </a>
        </li>
        <!--                    <li >PROMOTION</li>-->
        <li >
          <a  href="#">
            <i ></i>
            <p>Campaign <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>Report <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>New Report <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p> Skill </p>
          </a>
        </li>

        <li >
          <a  href="#">
            <i ></i>
            <p>Voice Mail </p>
          </a>
        </li>
        <li >
          <a  href="#"><i ></i>
                            <p>Chat <i ></i></p></a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#"><i ></i>
                            <p>Email <i ></i></p></a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#"><i ></i>
                            <p>SMS <i ></i></p></a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>


        <li >
          <a  href="#">
            <i ></i>
            <p>CRM <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#">
            <i ></i>
            <p>CRM Inbound <i ></i></p>
          </a>
          <ul >
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
      </ul>
    </nav>
  </div>
</aside>

CodePudding user response:

CSS Only Solution

If you wire up the menus as shown in the Bootstrap documentation then you won't need the custom JavaScript and can toggle the icons using only css. To do this, we only need to add a data-bs-toggle attribute, an id, and an href. Compare the original and modified code below for the changes that must be made to each of the collapsible menus.

Original:

  <a >
    <i ></i>
    <p>Dashboard
      <i ></i>
    </p>
  </a>
  <ul >
  ...

Modified:

  <a  href="#dashboard" data-bs-toggle="collapse">
    <i ></i>
    <p>Dashboard
      <i ></i>
      <i ></i>
    </p>
  </a>
  <ul  id="dashboard">
  ...

When a menu is opened, Bootstrap adds the collapsed class to the nav-link. And we can use that class to show or hide the first and last icon.

CSS:

.nav-link.collapsed i:first-child {
  display: inline;
}

.nav-link:not(.collapsed) i:first-child {
  display: none;
}

.nav-link.collapsed i:last-child {
  display: none;
}

.nav-link:not(.collapsed) i:last-child {
  display: inline;
}

.nav-link.collapsed i:first-child {
  display: inline;
}

.nav-link:not(.collapsed) i:first-child {
  display: none;
}

.nav-link.collapsed i:last-child {
  display: none;
}

.nav-link:not(.collapsed) i:last-child {
  display: inline;
}

/* original style */

.g-aside {
  background-color: #8c8c8c;
  width: 260px;
}

.nav {
  --bs-nav-link-padding-x: 1rem;
  --bs-nav-link-padding-y: 0.5rem;
  --bs-nav-link-color: var(--bs-link-color);
  --bs-nav-link-hover-color: var(--bs-link-hover-color);
  --bs-nav-link-disabled-color: #6c757d;
  display: flex;
  flex-wrap: wrap;
  padding-left: 0;
  margin-bottom: 0;
  list-style: none;
}

.submenu>li {
  list-style: none;
}

.g-sidebar .nav-link {
  position: relative;
  display: flex;
  font-family: quicksand, sans-serif;
  color: #fff;
  width: calc(260px - 1rem);
  transition: width .3s ease-in-out;
  list-style: none!;
}

.g-sidebar .nav-link p {
  margin-bottom: 0;
  padding-left: 1.4rem;
  display: inline-block;
}

.g-sidebar .nav-link p i,
.g-sidebar .nav-link p span {
  right: 1rem;
  position: absolute;
}
<aside >
  <div >
    <nav >
      <ul  id="nav_accordion">


        <li >
          <a  href="#dashboard" data-bs-toggle="collapse">
            <i ></i>
            <p>Dashboard
              <i ></i>
              <i ></i>
            </p>
          </a>
          <ul  id="dashboard">

            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>
        <li >
          <a  href="#ivr" data-bs-toggle="collapse">
            <i ></i>
            <p>IVR
              <i ></i>
              <i ></i>
            </p>
          </a>
          <ul  id="ivr">
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
            <li>
              <a  href="#"> <i ></i>
                <p>Submenu item 1</p>
              </a>
            </li>
          </ul>
        </li>

        <!-- other menus not shown -->


      </ul>
    </nav>
  </div>
</aside>


<link href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />

  • Related