How can I prevent an outside click event from triggering if it occurs on the button? (Using Vue 3)

Seeking assistance from anyone who can help me out. I have a popup and a button, and when I click the button, the popup window should open. Additionally, when I click outside the popup or on the button, the popup should hide.

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

I've implemented an example in a sandbox (unfortunately, it works locally but not in the sandbox environment. The code base is the same, and I'm puzzled by the reason for the issue in the sandbox. Hopefully, the example will be helpful)

Here's the directive I've implemented:

export default {
    name: 'click-outside',

    mounted: function (el, binding, vnode) {
        el.clickOutsideEvent = function (event) {
            event.stopPropagation();
            if (!(el === event.target || el.contains(event.target))) {
                binding.value;
            }
        };
        document.addEventListener('click', el.clickOutsideEvent);
    },
    unmounted: function (el) {
        document.removeEventListener('click', el.clickOutsideEvent);
    },
};

Simple markup example:

<template>
    <div class="component">
        <button ref="button" @click="isDisplay = true">Create</button>
        <div v-if="isDisplay" class="popup-box" v-click-outside="onClose">
            Test Popup Box
        </div>
    </div>
</template>

<script>
export default {
    name: 'HelloWorld',
    data() {
        return {
            isDisplay: true,
        };
    },

    method: {
        onClose() {
            this.isDisplay = false;
        },
    },
};
</script>

<style scoped>
.component {
    display: flex;
    justify-content: column;
}
.popup-box {
    position: absolute;
    left: 50%;
    top: 50px;
    transform: translateX(-50%);
    background: #f0f8ff;
    border-radius: 1px;
    box-shadow: 1px 1px 15px 0 rgba(0, 0, 0, 0.2);
    padding: 40px;
    color: #555585;
}
</style>

Global connection for directive:

import { createApp } from 'vue';
import App from './App.vue';
import ClickOutside from './directives/clickOutside.js';

const app = createApp(App);

app.directive('click-outside', ClickOutside);

app.mount('#app');

It works successfully... When I click the create button, 'isDisplay' is set to true (click event) and then false (directive), which is a problem I'm struggling to fix. I've tried using a ref for the button, but I'm not clear on how to handle the ref attribute in the directive (I couldn't find a way to check the ref and current click event to understand where the click event is triggered).

Answer №1

To make your code work correctly, make sure to add the v-click-outside directive to either your component or inner wrapper

<template>
    <div class="component" v-click-outside="onClose">
        <button ref="button" @click="isDisplay = true">Create</button>
        <div v-if="isDisplay" class="popup-box">
            Test Popup Box
        </div>
    </div>
</template>

Also, be sure to correct the misspelling in the method field to methods

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

Can you explain the distinction between these codes?

function Example() { this.display1 = function() { alert(1) } } Example.prototype.display2 = function() { alert(2) } var e = new Example e.display1() e.display2() display1 and display2 both have the ability to trigger an alert showing a number. Do yo ...

How can JavaScript pass a variable through the URL?

I am attempting to pass a variable through the URL: http://localhost/new_wiki/test.php?id=http://example.com In my code, I have var first = getUrlVars()["id"];. This line is supposed to pass the value but it doesn't seem to be working. Can someone pl ...

JQuery grid pagination bar mysteriously missing

I'm having an issue with a Jquery grid that is built on an HTML table. I've properly configured the grid properties, including implementing pager functionality with a page size of 10. However, I am unable to see the page up and page down buttons ...

Using JavaScript variables within an @if statement in Laravel within the innerHTML segment

How can I incorporate a JavaScript variable 'x' into an @if statement in Laravel? I have tried placing it both inside and outside of the @if statement. When placed outside, it works perfectly fine, but I really need to perform an action based on ...

Node.js encountering an empty array from an API request

In the 'product.js' file, there seems to be an issue with the API call '/achaar/products/1'. The value of val is empty when logging it in the console. Other API calls like '/achaar/products' are functioning correctly, but spec ...

Display a string variable in a field using JavaScript and JQuery

I am currently coding in JavaScript using JQuery, and I am facing an issue when trying to display the content of variables in a field. Here is my code snippet: function editEvolution(pos, nature, desc, di) { $('#diE').val(di); $(&apo ...

Guide on Modifying the color of a selected link tag

Here is the code snippet for a link tab: HTML <div class="sortLinks right"> <label>Sort by</label> <a onclick="javascript:SortOrder('DATE')" href="#">Date Modified</a> <span class="sort_sep">& ...

Require the implementation of seamless scrolling when clicking on an anchor tag with a specific ID, as opposed to the abrupt jumping to the corresponding

<div id="slider"> <div id="pro1"></div> <div id="pro2"></div> <div id="pro3"></div> </div> <div id="thumb"> <a href="#pro1"> <img id="tpro1" src="projects/tpro5.jpg" style="hei ...

Navigating through search results on an XML page using jQuery

Context: I am currently facing a challenge involving the integration of Google search outcomes into a webpage I'm constructing. These findings are presented in XML format. My current approach to importing the XML is as follows: if (window.XMLHttpReq ...

What is the proper way to specify the background image path in CSS?

My CSS file is located at: Project/Web/Support/Styles/file.css The image I want to use is found here: Project/Web/images/image.png I am attempting to include this image in my CSS file. I have tried the following methods: 1) background-image: url(/images ...

What is the best way to acquire an ID that is generated dynamically?

Being new to javascript and ajax, I am facing a challenge. I have a while loop with 2 buttons, both of which seem to function correctly, except for one small issue... The product-id is only being passed for the first or last element in the loop. How can I ...

Angular2 data binding does not update when properties change

I'm struggling to establish the connection between the fields and the component in order for them to update when the properties change in OnDataUpdate(). The field "OtherValue" successfully binds two ways with the input field, and the "Name" field di ...

Is it more important to focus on passing props or making API requests the top priority in your web application structure

Context Currently, I am working on a Vue App utilizing the Composition API. My backend serves as the source of data for loading pages and components. Inquiry When it comes to structuring my app's architecture, should I prioritize passing props thro ...

Discovering the perfect text-to-icon matching technique with Vue.js, Vuetify, and Jest's test-utils

Looking at the HTML code generated below: <a href="#" class="primaryInversed v-btn v-btn--large v-btn--round" <div class="v-btn__content">STOP! <i aria-hidden="true" class="v-icon v-icon--right material-icons">pause_circle_outline& ...

The error message that you are seeing is indicating that the `contracts` property of `this.state

Despite having encountered this issue before, I am still struggling to find a solution. The code snippet for fetching data is as follows: async componentDidMount(){ try { const res = await fetch('https://example.com/data.json'); ...

What could be the reason for my ajax request coming back with no data?

When I make this ajax request: $.ajax({ type: "POST", url: "/admin/RoutingIndicators/Add", data: { newSecondaryRI: newRi }, success: function () { alert('hit'); document.location.reload(true); }, error: fu ...

Learning how to access my CSS file using Express and Node.js

I am new to using express and node.js. I am trying to develop my app, but for some reason, my style.css file is not being recognized and I am unsure why. Initially, I attempted to use .scss files, but after researching, I discovered that it was not possi ...

React JS does not allow TextField and Select to change

I am relatively new to full stack development and I am currently working on a project to enhance my understanding of frontend development with React JS. While working on this project, I have been using Redux without any issues so far. However, I am facing ...

AngularJS Perspectives: Unveiling the Secrets of Successful Implementation

Do you have any tips on troubleshooting AngularJS views? I found a demo at AngularJS: ngView, but the provided jsfiddle doesn't seem to work. I've been trying to play around with it, but still haven't had any success. This is the code I&apo ...

Issue with dynamically filling a form field using ValidityState

I have been utilizing the ValidityState interface for client-side form validation, but I've encountered an issue. Whenever my form is populated programmatically, such as after making a call to a third-party API, the tooLong state always returns false, ...