Managing the dropdown state within a dynamically generated list of dropdowns with VueJS

I'm currently facing an issue with managing the open/close state and value for multiple dropdowns in a dynamically created list. When I use a single dropdown, I can utilize an "isOpen" variable within data(), but in a list scenario, all the dropdowns operate in sync; opening and closing simultaneously on click, and displaying the same selected values. It almost seems like they are identical dropdowns.

I am unsure about how to leverage the key of the outer list to differentiate each dropdown from one another, and/or assign a unique value to each. Any assistance on this matter would be greatly appreciated.

// main list
<div
  class="main-list"
  v-for="(item, index) in list"
  :key="index"
>
  <div class="list-item">
    <h1>Item Title</h1>
    <p>Description</p>

    // dropdown for this item in above v-for
    <div
      @click="isOpen = !isOpen"
      :class="{ 'is-open': isOpen }"
      class="dropdown-wrap"
      :key="index"
    >
      <div class="dropdown-title">
        {{ selectedLocation ? selectedLocation.location_name : "Select Location" }}
      </div>
      <ul class="locations-list">
        <li
          class="location"
          v-for="(item, index) in locations"
          :key="index"
          @click="setLocation(item)"
        >
          <a
            class="location-link"
            :aria-label="item.location_name"
          >
            {{ item.location_name }}
          </a>
        </li>
      </ul>
    </div>


  </div>
</div>

Answer №1

One issue is that the way you are declaring isOpen makes it specific to mainList.vue, when it should be independent and belong to each dropdown component.

A better approach would be to create a separate Vue component called Dropdown and move all the logic there:

Dropdown.vue

<template>
 <div class="list-item">
    <h1>Item Title</h1>
    <p>Description</p>

    // dropdown for this item in above v-for
    <div
      @click="isOpen = !isOpen"
      :class="{ 'is-open': isOpen }"
      class="dropdown-wrap"
      :key="index"
    >
      <div class="dropdown-title">
        {{ selectedLocation ? selectedLocation.location_name : "Select Location" }}
      </div>
      <ul class="locations-list">
        <li
          class="location"
          v-for="(item, index) in locations"
          :key="index"
          @click="setLocation(item)"
        >
          <a
            class="location-link"
            :aria-label="item.location_name"
          >
            {{ item.location_name }}
          </a>
        </li>
      </ul>
    </div>


  </div>
</template>

Remember to transfer all related data/methods from mainList to Dropdown.vue (such as isOpen, selectedLocation, ...)

Then in mainList.vue, simply call out the Dropdown component like so:

<div
  class="main-list"
  v-for="(item, index) in list"
  :key="index"
>
 <drop-down />
</div>

Now each Dropdown will have its own independent isOpen property and won't be dependent on each other.

Answer №2

To ensure each click triggers a unique action, it's important to designate isOpen as distinct for all dropdowns.

Consider using isOpen[index] or another method that works best for your needs.

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

The issue with a Bootstrap modal form integrated with JavaScript and PHP is that it fails to send emails upon submission

I have constructed this webpage with a button that activates a modal containing a contact form. <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#stayInformed">Stay Informed</button> My aim is to submit the form ...

I am looking to implement an animation that automatically scrolls to the bottom of a scrollable DIV when the page is loaded

My DIV is configured with overflow-y set to scroll. .scrolling-div { width: 85%; height: 200px; overflow-y: scroll; } If I have an abundance of content within this div, my goal is for it to automatically scroll to the bottom upon loading the page. I am ...

Transform PDF files into PNG format directly in your web browser

I am currently utilizing Vue.js and attempting to convert a PDF file to PNG or another image format directly within the browser. My current setup involves reading the PDF from a URL using PDF.js along with the Vue.js component pdfvuer. let instance = this ...

Organizing communications in NodeJS messaging application

My latest project involves creating a chat room using NodeJS and socket.io which allows multiple users to connect with unique usernames. Everything is running smoothly, except for one minor issue. I want the messages sent by me to appear in a different co ...

Setting a unique identifier for a newly created element in JavaScript and the DOM

Is there a way to assign an element ID to a newly created element using JavaScript DOM? The code I've written generates a table that is displayed when a button is clicked. I'm looking to give this table a unique ID so it can have a distinct sty ...

Identification of absence of file selected in input file control

Imagine a scenario where I need to select an image to display on the screen from a select control. If the desired image is not available, I want to be able to choose it from the disk and add this option to the select control while automatically selecting i ...

Vue component not responding to @click event

I have a Vue component where I have written a function to increase the value of likes by 1 when a button is clicked. However, this functionality doesn't seem to be working as expected. I initially tried writing it directly inside the component like th ...

What is the significance of $() in jQuery?

I understand that $() is a selector, but I find it puzzling as to what it actually selects since there is nothing inside the parentheses. Is this a common practice or frowned upon in coding conventions? An example of where I have seen it used is when maki ...

The functionality of watch is incompatible with both Pinia and the Composition API

Here is the code snippet for store.js: export default defineStore('global', () => { const packagesList = reactive([]) function getSearch() { setTimeout(() => { packagesList.splice(0, packagesList.length, ... ...

Creating dynamic forms using AngularJSIn this tutorial, we will explore how to generate

I need help creating an HTML form. I have an object that stores an array of form elements like { "formFields": [ { "type": "select", "label": "Fabric", "name": "fabric", "options": [ ...

Guide on setting up a new NPM and JavaScript project within Visual Studio 2015

Whenever I watch tutorials, they always mention having a "special npm reference" that I seem to be missing. https://i.sstatic.net/I52dn.png All I can find are the "normal" references (.net assemblies). I also can't locate any project type labeled as ...

Caution: When using Array.prototype.reduce(), make sure the arrow function returns a value

const filteredParams = [...appliedFilters].reduce((prev, curr) => { if (curr.key !== "multi") return { ...prev, ...curr.selectedValue.params }; return; }, {}); When I run this code, I encounter the following warning message in ...

eBay API request error: "You do not have the necessary permissions to complete the request."

While working on integrating the eBay API, I encountered an issue with creating a payment policy. Following the instructions provided in this guide , I generated a token and sent it using Postman. However, I received an error: { "errors": [ ...

Remove the class upon clicking

I recently created a toggle-menu for my website that includes some cool effects on the hamburger menu icon. The issue I am facing is that I added a JavaScript function to add a "close" class when clicking on the menu icon, transforming it into an "X". Whil ...

What is the easiest way to choose a child vertex with just one click on mxgraph?

I have nested vertices and I'm looking to directly select the child vertex with just one click. Currently, when I click on a child vertex, it first selects the parent vertex instead. It's selecting the parent vertex initially: To select the ch ...

gain entry to the chart object within highcharts

Having trouble accessing the chart object in Highcharts using the AngularJS directive HIGHCHARTS-NG. var chart = $scope.chartConfig.getHighcharts(); console.log("chart", chart); Encountering an error: $scope.chartConfig.getHighcharts is not a function. ...

When utilizing the @Prop decorator in TypeScript, the compiler throws an error prompting the need to initialize the prop

Currently, I am utilizing Vue in combination with TypeScript along with the 'vue-property-decorator' package. When attempting to utilize a prop as shown below: @Prop({ default: '' }) private type: string An error is triggered by the ...

Creating a see-through effect in Three.js with React Fiber

I'm currently working with react fiber and struggling to make the background of my child scene transparent. Below is my root component containing the main Canvas element: export const Splash = () => { const { intensity, distance, colo ...

Difficulty in transmitting two boolean values using ajax and setTimeout()

I am working on two functions that are supposed to send either 0 or 1 to a PHP page using AJAX. When a key is pressed on the keyboard, the function that sends 1 should start, followed by the second function that sends 0 three seconds later using setTimeout ...

Tips for transferring information between routes in Node.js using Express.js

How can I add a specific attribute to the request object and access it from another route after redirection? Below is an example of what I am looking for: const express = require('express') const app = express() app.get('/test1',(req, ...