With a single click, Clickaway is triggered not once, but twice

I am working on creating a filter component where I can pass filter options down to my child component. Each filter has a click event to open the filter for user selection, as well as a v-on-clickaway event that closes the options when the user clicks away. Here is how my child component is structured:

        <div
          v-for="filter in filters"
          id="desktop-menu-0"
          class="relative inline-block text-left"
          @click="toggle(filter.id, true)"
          v-on-clickaway="toggle(filter.id, false)"
        >...</div>

Below is the script for the child component:

<script lang="ts">
import { mixin as clickaway } from 'vue-clickaway'

export type FilterOptionT = {
  text: string
  value: unknown
  selected: boolean
}
export type FilterT = {
  id: any
  text: string
  open: boolean
  values: FilterOptionT[]
}
export default {
  mixins: [clickaway],
  props: {
    filters: {
      default: () => [] as FilterT[],
    },
  },
  setup(props, { emit }) {
    function toggle(id: any, state: boolean) {
      emit('toggleFilter', id, state)
    }

    return { toggle }
  },
}
</script>

This is how the parent component is integrated into the code:

<filterVue @toggleFilter="toggleFilter" :filters="filters"></filterVue>

let filters = ref<FilterT[]>([
  {
    open: false,
    text: paths.members_table.status,
    id: 'status',
    values: [
      {
        selected: false,
        text: paths.statustexts.accepted,
        value: Userstatus.ACCEPTED,
      },
      {
        selected: false,
        text: paths.statustexts.asked,
        value: Userstatus.WAIT,
      },
      {
        selected: false,
        text: paths.statustexts.activated_eda,
        value: Userstatus.MC_ACTIVATED,
      },
    ],
  },
])

function toggleFilter(filterId: any, state: boolean) {
  console.log(state, filterId)
  let filterIndex = filters.value.findIndex((f) => f.id === filterId)
  if (filterIndex !== -1) {
    filters.value[filterIndex].open = state
  }
}

After clicking on the element, it logs 3 messages in the console:

https://i.sstatic.net/Z1FFn.png

The filter instantly closes, and I am trying to figure out what I might be doing wrong here.

Answer №1

To start, I recommend avoiding the use of a `toggle` method and instead directly changing the `close` property of your filters as shown below:

<div
   v-for="filter in filters"
   id="desktop-menu-0"
   class="relative inline-block text-left"
   @click="filter.open = true"
   v-on-clickaway="filter.open = false"
>...</div>

Additionally, it seems like the console output you are witnessing may be related to the `v-on-clickaway` event. It's possible that it is not functioning correctly and causing bubbling issues. Consider using a different library such as onClickOutside from VueUse.

UPDATE

I just noticed something that could potentially resolve your problem: assigning the same id, `desktop-menu-0`, to all your filters. Try giving each filter a unique id to distinguish between them.

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

extract data from a dropdown menu with playwright

I'm having a tough time figuring out how to select the "All" option in a dropdown menu and extract all the data from that page. I've found some related posts, but they don't quite match my scenario. The "select" element I'm working with ...

Issues with the styling of HTML code

Our website features a main menu with submenus that are intended to be displayed only when hovering over the main menu. However, upon loading the site, the submenu is already visible causing an issue. We need the submenu to appear only when the main menu i ...

How to effectively sort through users in Angular 6 without the need for a custom pipe

I am looking to customize the user.component template by implementing a filter functionality that will display only the users in the array that match the string entered in the text input field. Is there a way to bind the input value to the view without rel ...

What is the best way to transform a GET request with a query string into a promise?

After successfully making a request with querystring params, I encountered an issue while trying to promisify my request: // Works var Promise = require("bluebird"); var request = Promise.promisifyAll(require("request")); request.get({ url: 'htt ...

Tips on transmitting JSON data from a Spring controller to JavaScript

Does anyone have experience with sending a JSON object from a spring controller to JavaScript and receiving it using AJAX? I would appreciate any guidance on how to accomplish this. ...

AngularJS - Use promise instead of returning a data object

I am currently working on a project using AngularJS. Within my service.js file, I am attempting to retrieve some values. However, instead of receiving the actual data, I am getting back a promise object with some $$variables along with the desired data. ...

What's the Reason Behind My Array Populating on Rebuild but Not on Page Refresh?

I am currently utilizing a tech stack that includes Vue 3 with Composition API, a Pinia store, TypeScript, a SQL backend, and Fetch to retrieve data through my .NET 6 API. Within my codebase, I have a User.ts class: export default class User { userNam ...

Is it possible to retrieve data from a promise using the `use` hook within a context?

Scenario In my application, I have a component called UserContext which handles the authentication process. This is how the code for UserProvider looks: const UserProvider = ({ children }: { children: React.ReactNode }) => { const [user, setUser] = ...

JavaScript allows for the hiding of the Android navigation bar on web apps in Chrome, which includes the virtual back, home screen, and other buttons

In the process of developing a web application, I am aiming to provide users with a fully immersive fullscreen experience. This entails hiding not only the Chrome address bar at the top but also the navigation bar at the bottom (which includes virtual back ...

What is the best way to change JSON into a key-value dictionary with TypeScript?

Here is a JSON example that I am working with: { "MyTest:": [{ "main": { "name": "Hello" }, "test2": { "test3": { "test4": "World" }, ...

Incorporating components into Vue while utilizing Flask poses a challenge

Currently, I am working on a project that involves Flask and Vue. I am attempting to add a carousel to my website, but I am running into difficulties with creating and importing components for Vue when following tutorials. Here is my current file structure ...

Angular is unable to eliminate the focus outline from a custom checkbox created with Boostrap

Have you noticed that Angular doesn't blur out the clicked element for some strange reason? Well, I came up with a little 'fix' for it: *:focus { outline: none !important; } It's not a perfect solution because ideally every element sh ...

What is the process for creating a downloadable link or button?

Here's the scenario I'm dealing with: I have a dynamic website that includes a form with a "select" dropdown menu, followed by a link or button. When a user clicks on the link: If the selected option is "display," the data is shown using AJAX ...

Firefox version 78.0.1's Responsive Design Mode fails to provide accurate window.innerWidth values after screen orientation change

Could this be a bug specific to Firefox, or have I made an error somewhere? When testing in Chrome or on an actual device like Android, everything works fine. It appears to be an issue only when using Firefox's Responsive Design Mode. Below is the c ...

The distortion of Blender animation becomes apparent once it is imported into three.js

I've been working on a project where I'm incorporating animations into a scene using a combination of blender and three.js. It took me several hours of trial and error to finally get the model and animation successfully imported into three.js. I ...

Invoking functions from a JS file that has already been loaded

I am currently utilizing jQuery for my project. Within a JS file named super.js, I have the following code: $("#content").load("/profile"); function setHash(hash) { location.hash = "#/:-)/"+hash; } The "/profile" path is used to load an external JS f ...

AngularJS Default Option Selection

I am encountering some difficulties with the preselection of a select-input in angularJS. The select-box is being populated by an array. <select class="form-control" ng-model="userCtrl.selected_country" ng-options="country.name for country in userCt ...

The numerical value fluctuates upon utilizing JSON.parse( )

I am currently utilizing Node/Express to send API requests to the unofficial Vine API. The data returned by the GET https://api.vineapp.com/users/search/ route undergoes changes during parsing. This is my code snippet: request({ url: 'https://api.v ...

Parsing JSON dynamically using JavaScript

Below is a JSON object that needs to be parsed to extract values only from the last children available in the list for each object: { "projectInfo": { "cabinetInfo": [ { "nodeName" ...

Making an HTTP request using AngularJS takes significantly more time than directly accessing the endpoint through a web browser

I'm currently working on improving the functionality of a WordPress website using AngularJS. To achieve this, I am utilizing the WP-API (v2) plugin to create custom endpoints and consuming them on the front end with the Angular $http service. Below i ...