Skip to main content

React JS : close all other open sub-menu when other parent menu item is clicked?

i have a sidebar menu i want to close other submenu when current is clicked : so when i click to parent menu or another submenu the last submenu must be closed.

what can i add to my code to achieve this goal can any one help me on that.

sidebar.jsx

import React,{useState,useEffect} from 'react';
import { Link ,withRouter} from 'react-router-dom';
import './sidebar.css'
import logo from '../logo_radeeo.jpg'
import { useSelector,useDispatch } from "react-redux"
import {FiHome} from 'react-icons/fi';
import {CgMenuGridR} from 'react-icons/cg'
import {HiOutlineDesktopComputer} from 'react-icons/hi'
import {VscChromeClose} from 'react-icons/vsc'
import {GiHamburgerMenu} from 'react-icons/gi'
import { showorhidesidebar } from '../../actions/showorhideAction';
import {MdPerson}from 'react-icons/md'
import { isAuthenticated } from '../../auth/helpers';
import $ from 'jquery';
import { SidebarData } from './SidebarData';

import SubMenu from './SubMenu';
import Media from 'react-media'
const Sidebar = (props) => {
    // const[state,setstate]=useState(true)
    const dispatch=useDispatch();
  
    const state = useSelector((state) => state.showorhidereducers);

    
    const openNav=() =>{
        
       
          dispatch(showorhidesidebar(true))
         
            if (
              document.getElementById("mySidenav") &&
              document.getElementById("main")
            ) {
              document.getElementById("mySidenav").style.width = "277px";
              document.getElementById("main").style.marginLeft = "277px";
              document.getElementById("mySidenav").classList.remove("active")
            }
          }
           
      
      const closeNav=() =>{
       
        
        dispatch(showorhidesidebar(false))
          if (
            document.getElementById("mySidenav") &&
            document.getElementById("main")
          ) {
            document.getElementById("mySidenav").style.width = "90px";
            document.getElementById("main").style.marginLeft = "90px";
            document.getElementById("mySidenav").classList.add("active")
          }
       
       
      }
   const sidenavdesktop=()=>{
     return(
    <div id="mySidenav" className={`sidenav`}>
    <span className="titleapp">Gestion Stock</span>
    {state ?   <span className="closebtn" onClick={closeNav}>&times;</span> :
    <GiHamburgerMenu className="humberger"  onClick={openNav}/>}
             {SidebarData.map((item,index)=>{
        return <SubMenu item={item} key={index} state={state} props={props} />
 })}


</div>
     );
   }

  useEffect(()=>{
    if (window.matchMedia("(min-width: 728px)").matches) {
     
      openNav()
    } else {
     
      closeNav()
    }
  },[])
    return (
        <div>
            {isAuthenticated() ?(
            sidenavdesktop()
                           
        ):""}
        </div>
      );
    }
export default withRouter( Sidebar);

SubMenu.jsx

import React, { useState,useEffect } from 'react'
import { Link,withRouter } from 'react-router-dom';

function SubMenu({item,state,props}) {
    const [subnav, setSubnav] = useState(false);
    const showSubnav = () => setSubnav(!subnav);
    const isActive = (history, path) => {
      if (history.location.pathname === path) {
        
        return {
          background:"#172b4d",
          width: '100%'
        }
       
      } else {
        return {  
          width: '100%'
        }
       
      }
    };

    
    return (
        <div>
            <ul>
            <li>
                
                <Link to={item.subNav ?"#":item.path} className="" style={isActive(props.history,item.path)}  onClick={item.subNav && showSubnav  } 
                
                >
                  <span className="icon"><i className={item.icon} ></i></span>
                  <span className="title">{item.title}</span>
                  {item.subNav &&(
                      item.subNav && subnav
                        ? item.iconOpened
                        : item.subNav
                        ? item.iconClosed
                        : null
                  )}
                </Link>
               
                {
                  subnav && 
                
                <ul className={state?"show":"showleft"}>

                
                {subnav && item.subNav && item.subNav.map((item,index)=>{
                    return(
                        <li key={index}  >
                      <Link to={item.path} style={isActive(props.history,item.path)  } onBlur={()=>setSubnav(false)}    >
                      
                      <span className="title">{item.title}</span>
                    </Link></li>
                    );
                })}
                </ul>
                }
              </li>
              
             
            </ul>
        </div> 
       
    )
}

export default withRouter(SubMenu)

SidebarData.jsx

import React from 'react';


export const SidebarData = [
  {
    title: 'Home',
    path: '/',
    icon: "fas fa-dice-d6"
  },
  {
    
    title: 'Administration',
    path: '#',
    icon: "fas fa-dice-d6",
    iconClosed: <span className="fas fa-caret-down caret"></span>,
    iconOpened: <span className="fas fa-caret-up caret"></span>,

    subNav: [
      {
        title: 'Gestion des admins',
        path: '/admin/listusers',
        icon: "fas fa-dice-d6"
      },
      {
        title: 'Gestion agents',
        path: '/admin/agents',
        icon: "fas fa-dice-d6"
      }
    ]
  },
  {
    title: 'Categories',
    path: '/categories',
    icon: "fas fa-dice-d6"
  },
  {
    title: 'Saisie Materiels',
    path: '/addmtrl',
    icon: "fas fa-dice-d6"
  },

  {
    title: 'Affectation Materiels',
    path: '/affctmtrl',
    icon: "fas fa-dice-d6",
    iconClosed: <span className="fas fa-caret-down caret"></span>,
    iconOpened: <span className="fas fa-caret-up caret"></span>,
   
  }

];

sidebar.css

*{
    margin: 0;
    padding: 0;
    list-style: none;
    box-sizing: border-box;
    text-decoration: none;
    font-family: 'Montserrat', sans-serif;
  }
  
 body {
     overflow-x:hidden;
 }
 

 .sidenav {
    z-index: 123548451235 !important;
    height: 100%;
    width: 277px;
    position: fixed;
    z-index: 1;
    top: 0;
    left: 0;
    background-color: #011627 !important;
    overflow-x: hidden;
    transition: 0.5s;
    padding-top: 80px;
  }
  .sidenav a:hover,a.active {
    background:#172b4d;
    width: 100%;
  }

   .sidenav ul li a span.caret{
    position: absolute;
    right: 22px;
    /* transform: translatex(-50%); */
  
    
  }
  .sidenav  ul li a{
    color: #fff;
    font-size: 18px;
    padding: 20px 30px;
    white-space: nowrap;
    display: flex;
    align-items: center;
    margin-bottom: 1px;
    transition: all 1s ease;
  
  }
  .titleapp{
    left: 30px;
      top:23px;
      right:19px;
      position:fixed;
    font-size: 20px;
    font-weight: bold;
    color: white;
   }
  .sidenav ul ul li a{
    font-size: 17px;
    color: #e6e6e6;
    padding-left: 40px;
  }
  .sidenav.active ul ul li a{
    padding-left: 20px;
  }

  .sidenav.active  ul li a span.title,
  .sidenav.active ul li a span.caret ,
  .sidenav.active .titleapp span.title,
  .sidenav.active .titleapp
  {
    display: none;
  }

  .sidenav.active  ul ul li a span.title{
    display: block;
    transition: all 1s ease;
  }
  .sidenav ul li a span.title,
  .sidenav.active .titleapp span.title

  {
    display: block;
    transition: all 0.3s ease;
  }
   .sidenav ul ul{
    position: static;
    display: block;
    transition: all 1s ease;
  }
  .sidenav.active ul.showleft
 {
  position: fixed !important;
  display: block !important;
  left: 90px;
  transform: translateY(-40%);
 background-color:#011627 ;

  /* top: 60px; */
 }
  .sidenav .closebtn,.humberger {
    position: absolute;
    top: 10px;
    right: 30px;
    font-size: 36px;
    margin-left: 50px;
    color:white;
    cursor: pointer;
  }

i have tried to add this property onBlur in submenu item like this

 <Link to={item.path} style={isActive(props.history,item.path)  } onBlur={()=>setSubnav(false)}  >

but it doesn't work like what i want : when i select a second item in submenu the submenu is closed i don't want that . i want to close when the parent is clicked

my question is similar to this question but now for react js not jquery

Via Active questions tagged javascript - Stack Overflow https://ift.tt/2FdjaAW

Comments

Popular posts from this blog

Why is my reports service not connecting?

I am trying to pull some data from a Postgres database using Node.js and node-postures but I can't figure out why my service isn't connecting. my routes/index.js file: const express = require('express'); const router = express.Router(); const ordersCountController = require('../controllers/ordersCountController'); const ordersController = require('../controllers/ordersController'); const weeklyReportsController = require('../controllers/weeklyReportsController'); router.get('/orders_count', ordersCountController); router.get('/orders', ordersController); router.get('/weekly_reports', weeklyReportsController); module.exports = router; My controllers/weeklyReportsController.js file: const weeklyReportsService = require('../services/weeklyReportsService'); const weeklyReportsController = async (req, res) => { try { const data = await weeklyReportsService; res.json({data}) console...

How to show number of registered users in Laravel based on usertype?

i'm trying to display data from the database in the admin dashboard i used this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count(); echo $users; ?> and i have successfully get the correct data from the database but what if i want to display a specific data for example in this user table there is "usertype" that specify if the user is normal user or admin i want to user the same code above but to display a specific usertype i tried this: <?php use Illuminate\Support\Facades\DB; $users = DB::table('users')->count()->WHERE usertype =admin; echo $users; ?> but it didn't work, what am i doing wrong? source https://stackoverflow.com/questions/68199726/how-to-show-number-of-registered-users-in-laravel-based-on-usertype

The number of nodes and edges I calculated manually and by a method provided by networkx library dont match

I am trying to analyse a graph using networkx library in Python. I have implemented a function that returns the nodes and edges of that graph. After that I counted the number of nodes and edges by implementing the len() function for nodes and edges, which gave me 17 for both nodes and edges. However, when I used the method graph.number_of_nodes() of networkx library it gave me 53. My code: import pandas as pd import networkx as nx import matplotlib.pyplot as plt header_list = ["a","b","w"] E =pd.read_csv("aves-barn-swallow-contact-network.edges",sep=" ",header= None,names=header_list) # print(E.head()) # prints first few rows of the csv file G = nx.from_pandas_edgelist(E,"a","b",["w"]) nx.draw(G) plt.show() class GraphAnalyse: #finding nodes and edges def nodeEdge(self,Graph): nodes = Graph.nodes() edges = Graph.edges() ...