Trigger the immediate collapse of all active elements in the Vuetify v-list-group

I have successfully constructed a navigation within a permanent drawer using the v-list component, following the provided instructions.

When the drawer is collapsed, only the icons are displayed. Upon hovering over the collapsed drawer, it expands to reveal the names of the navigation items.

Some of the items are grouped, and clicking on them reveals sub-items.

The issue arises when I attempt to collapse the active sub-items when the drawer itself collapses.

Below is the code snippet:

<v-navigation-drawer
  v-model="mainSidebarDrawer"
  :mini-variant.sync="mini"
  fixed
  expand-on-hover
  permanent
>
  <v-list>
    <template v-for="(n, i) in nav">
      <v-list-item v-if="n.to" :key="`${i}-a`" :to="n.to" link>
        <v-list-item-icon>
          <v-icon small>{{ n.icon }}</v-icon>
        </v-list-item-icon>
        <v-list-item-content>
          <v-list-item-title>{{ n.label }}</v-list-item-title>
        </v-list-item-content>
      </v-list-item>
      <v-list-group
        v-if="n.subItems"
        :key="`${i}-b`"
        :prepend-icon="`${n.icon} fa-em`"
        :value="subItemsValue"
        append-icon="fas fa-chevron-down fa-sm"
      >
        <template v-slot:activator>
          <v-list-item-content>
            <v-list-item-title>{{ n.label }}</v-list-item-title>
          </v-list-item-content>
        </template>
        <v-list-item
          v-for="(s, y) in n.subItems"
          :key="y"
          :to="s.to"
          link
          class="pl-8"
        >
          <v-list-item-icon>
            <v-icon small>{{ s.icon }}</v-icon>
          </v-list-item-icon>
          <v-list-item-content>
            <v-list-item-title>{{ s.label }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list-group>
    </template>
  </v-list>
</v-navigation-drawer>

The Vue code contains:

data() {
  return {
    mainSidebarDrawer: true,
    mini: true,
    subItemsValue: false
  }
}

To summarize:

  1. The drawer is initially collapsed showing only the icons
  2. Expanding on hover displays both icon and text
  3. Clicking on a list group expands the sub-items
  4. Moving the mouse away from the drawer causes it to collapse like at point 1
  5. List groups remain expanded. I would like them to collapse as well

I attempted to listen for changes in the mini property and implemented the following solution:

<v-navigation-drawer
  ...
  @update:mini-variant="collapseSubItems"
</v-navigation-drawer>

methods: {
  collapseSubItems() {
    if (this.mini) {
      this.subItemsValue = false
    }
  }
}

Unfortunately, the subItemsValue does not change. I also tried moving it inside the v-model. Any suggestions on how I can achieve my desired result? Thank you.

Answer №1

To optimize the code, consider implementing an "active" state variable for each navigation item instead of a single variable like subItemsValue. Utilize the transitionend event to revert the open navigation item back to active: false...

<v-navigation-drawer
      v-model="mainSidebarDrawer"
      permanent
      expand-on-hover
      @transitionend="collapseSubItems"
    >
    <v-list>
        <template v-for="(n, i) in nav">
          <v-list-item v-if="n.to" :key="`${i}-a`" :to="n.to" link>
            <v-list-item-icon>
              <v-icon small>{{ n.icon }}</v-icon>
            </v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title>{{ n.label }}</v-list-item-title>
            </v-list-item-content>
          </v-list-item>
          <v-list-group
            v-if="n.subItems"
            :key="`${i}-b`"
            :prepend-icon="`${n.icon} fa-em`"
            v-model="n.active"
            append-icon="fas fa-chevron-down fa-sm"
          >
            <template v-slot:activator>
              <v-list-item-content>
                <v-list-item-title>{{ n.label }}</v-list-item-title>
              </v-list-item-content>
            </template>
            <v-list-item
              v-for="(s, y) in n.subItems"
              :key="y"
              :to="s.to"
              link
              class="pl-8"
            >
              <v-list-item-icon>
                <v-icon small>{{ s.icon }}</v-icon>
              </v-list-item-icon>
              <v-list-item-content>
                <v-list-item-title>{{ s.label }}</v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list-group>
        </template>
     </v-list>
 </v-navigation-drawer>

 collapseSubItems() {
      this.nav.map((item)=>item.active=false)
 },

Demo: https://codeply.com/p/qzrKTPSzrB

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

What is the most effective approach for returning varying object types based on conditions in JavaScript?

Currently, I am working on creating a function to validate input arguments. However, I am unsure if the method I am using is considered best practice. The validation function I have created looks like this: const isValidStudyId = (id) => { if (valida ...

Webpack 5 now supports the mini-css-extract-plugin for efficiently extracting scss files

I am currently in the process of transitioning a webpack configuration from version 4 to include the mini-css-extract-plugin. However, I have encountered an issue where none of my first-party application CSS (SCSS) is being injected into the main app.css f ...

Loading bar for AngularJS material framework

Is there a way to integrate https://material.angularjs.org/latest/demo/progressLinear into my website so that it shows progress when a new view is loading? I'm trying to figure out how to obtain the value of the current page being loaded. Any suggest ...

Retrieve all `div` elements within the shadow root that have a matching class name

I have discovered a shadowRoot within my HTML page, which I am able to access using the following code snippet: var shadow = document.getElementById( "3rd-party-div" ).shadowRoot; Upon further examination, I noticed that there are ...

Capturing input and select values dynamically in JavaScript without explicitly targeting them

I'm currently working on a project that involves looping through a set of list items containing input and select boxes. My goal is to extract the values from these elements, perform a calculation based on those values, and store the results in an arra ...

Remove a specific EventListener that has been defined within a class

I am struggling to successfully remove an eventListener, but it seems like I'm missing a crucial step. Could somebody please point out why the code below is not effective in removing the event listener from the button? Even after attempting to bind ...

The search functionality for the MongoDB module is not functioning properly within my Next.js application

Working on my nextjs application, I have encountered an issue with using the mongodb node module to find all documents in one of my collections. Despite successful usage of .findOne and .updateOne for other pages like login and password reset, when I use . ...

Tips for resolving the error message "cannot read property of undefined"

I've been working on coding a Discord bot and I keep encountering an error when trying to check if "mrole" has the property "app". It's not functioning as expected and I'm puzzled by why this is happening. My intention is to retrieve the te ...

Express JS failing to detect the current environment

I have organized my application folder structure in the following way. app/ config/ app.js env.js server.js Every time I try to run my app.js file, it displays "server started at undefined". Here is a link to the code snippet: Gist Cod ...

Initially, the 'display none' CSS command may not take effect the first time it is used

I am currently working on a slideshow application using jquery.transit. My goal is to hide a photo after its display animation by setting the properties of display, transform, and translate to 'none' value. Although the slideshow application work ...

Tips for transferring information between different components through a collaborative service

Attempting to send data using a subject to another component for the purpose of earning, but experiencing difficulty retrieving the data. Below is the provided code snippet: app.component.ts import { Component } from '@angular/core'; import { s ...

Assistance with Redirecting Responses in Next.js API Routes

I'm currently working on implementing a login functionality in Next.js. I have made significant progress but I am facing an issue with redirecting to the homepage after a successful login. My setup involves using Next.js with Sanity as the headless CM ...

Utilize sceneLoader to import scene from JSON file

Trying to load a scene selected from my MONGODB and display it using SceneLoader in my client's browser, but encountering an issue: Uncaught TypeError: undefined is not a function Here is the code snippet causing the error: function shows ...

Could anyone assist me in finding a way to exclude a particular "class" from being iterated over while utilizing ng-repeat in Angularjs?

Utilizing AngularJS within the framework of my Bootstrap carousel has presented a challenge. When I implement the directive ng-repeat="album in ActiveSinger.albums" to loop through my array, it continuously adds the class "active" to each div element. This ...

Error: Unable to set headers after they have been sent in Express and Passport

Just starting out with node and web development, but giving it my all! Encountered this error message: can't set headers after they are sent This issue arose while using passport.js and bcryptjs compare method for password validation in a mean stac ...

How can Angular 7 incorporate inline JavaScript scripts in a component?

I am facing an issue while trying to integrate the places.js library into my Angular 7 project. I have added the necessary script in my 'index.html' file as follows: <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-prot ...

Jquery not functioning properly after invoking window location change

I have a function that sends a value to a php page and then executes some sql. Once the process is finished, I want to change the window location. Everything works fine without the window.location.href line, but when I include it, the page changes without ...

Having trouble establishing a basic websocket connection in NodeJS

I am currently following a tutorial on WebSocket protocol development from this link: . Upon visiting localhost:1337/index.html, I encountered the following error: This localhost page cannot be found. No webpage was found for the web address: http://loc ...

JavaScript can dynamically attach EventListeners to elements, allowing for versatile and customized event

I am currently populating a table using data from an XML file. One of the columns in the table contains links to more details. Due to the unique requirements of my web page setup (Chrome extension), I need to dynamically add an event handler when the table ...

Creating dynamic charts in Javascript using Firebase

My dad recently asked me to enhance our motor home by integrating an Arduino with Firebase to monitor the water and propane tanks. He's hoping to be able to check tank levels from his phone so he can see when they need refilling. I've successful ...