AngularJS closes when clicking anywhere except for the element itself

It's a common occurrence, for example, when you click on the inbox here on stackoverflow. I refer to the dialog or popup that appears as a thing.

There are two methods I am aware of to handle this:

  1. Creating an invisible overlay where the opened element has a higher z-index, and closing the thing by clicking on the overlay.
  2. Using a click event on the document to determine if the click was inside or outside the thing, and closing it accordingly.

In both cases, I would prefer to utilize ng-class to toggle the visibility of the thing.

How can I achieve this with Angular, so that it can be applied to any component (thing) I may add? It's not just one modal, but potentially multiple components with varying HTML structures and positions.

Which approach would be more efficient - document event, overlay, or something entirely different?

Considering that Angular does not have direct access to the DOM, the document event approach could pose challenges in determining if the click was on the thing element. This could be resolved by giving every thing the same class.

On the other hand, the overlay approach does not require direct references to DOM elements.

Both approaches would necessitate a unique variable in the $rootScope for ng-class to function properly. This raises the question of whether to stick with ng-class or opt for a custom solution.

These are just some initial thoughts - perhaps there is a different perspective to consider. Has anyone encountered this scenario before?

Answer №1

My approach to handling similar situations involves utilizing the inheritedData method to relay information to the click handler regarding its location:

  • Within the custom directive for the specific element, include a data variable using jqLite data to set element.data('myThing',true). To differentiate between multiple instances, a unique key may be necessary.

  • In the same custom directive, within a click event handler on document.body, you can verify

    angular.element(event.target).inheritedData('myThing')

Below is an example directive implementing this technique:

app.directive('thing', function($document,$window) {
  return {
    restrict: 'E',
    template: '<div><span>Inner thing</span></div>',
    replace: true,
    link: function(scope,element) {
      element.data('thing',true);

      angular.element($document[0].body).on('click',function(e) {
        var inThing =  angular.element(e.target).inheritedData('thing');
        if (inThing) {
          $window.alert('in');
        } else {
          $window.alert('out');
        }
      })
    }
  }
});

View this technique in action on Plunker http://plnkr.co/edit/bRDLcLoesM7Z0BIxKxYu?p=preview

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

Guide on leveraging a private GitHub repository as a yarn dependency without installing internal dependencies

Recently, I have been attempting to incorporate a private GitHub repository as a dependency within multiple repositories at my workplace. Within the primary package.json file, our dependency is outlined as follows: "mycompany-models": "https://github.com ...

Ways to change the chart type in ApexCharts

I'm seeking a way to change the chart type of an existing ApexCharts that has already been rendered. After reviewing the methods, I attempted to use the updateOptions() method, but encountered the error: Uncaught TypeError: Cannot read property &apos ...

What is the best way to achieve maximum height?

Currently, I am attempting to obtain the total height of the page in order to apply it to the styles, specifically for the darkMask class. The reason for needing this height is that when a certain action is triggered within the header, a dark overlay is a ...

Is it possible to execute a function once an element has finished loading?

I am facing a challenge with running the List_Sandbox functions after a specific each loop. This loop selects checkboxes that trigger a change event, rendering additional checkboxes that need to be selected. The issue arises when the List_Sandbox functio ...

React Native - encountering undefined setState when passing data

I'm attempting to transfer data or items from one screen to another upon tapping the send button. However, the this.setState function in my "_onPress" method doesn't seem to be working correctly. When I tap the send button, the alert displays "un ...

Angular UI: The dialogProvider is throwing an unknown provider error

Attempting to emulate a basic dialog with a close button using Angular UI, following the example provided here: https://github.com/angular-ui/bootstrap/blob/master/src/dialog/README.md. However, facing issues with injecting the 'dialog' parameter ...

The issue of 'position: fixed' not properly functioning within the Materialize CSS modal

My goal is to have the header of the Modal stay fixed while scrolling, but for some reason, the option position:fixed; is not working. I am currently using Materialize CSS to build the modal and surprisingly, position:sticky; is working. $(document).rea ...

Error occurred during download or resource does not meet image format requirements

Encountering an issue when attempting to utilize the icon specified in the Manifest: http://localhost:3000/logo192.png (Download error or invalid image resource) from the console? import React from 'react'; import Logo from '../Images/logo1 ...

Dominate with asyncCommand and Ajax in MVC ActionResults

I am currently diving into front-end development and working on a project that involves fixing bugs. Right now, I am utilizing Knockout/MVC ActionResults. One of my tasks is to modify a form so that it cannot be submitted with a double click. I initially ...

Serverless Functions in ZEIT Now - Customizing Routes with Parameters

I successfully implemented 4 serverless routes /api/list (GET) /api/add (POST) /api/update/:id (PUT) /api/remove/:id (DELETE) These routes were added to the api/now.json file in the following format: {"src": "/api/list", "dest": "./list.js", "methods": ...

Error TS2322: Type 'boolean' cannot be assigned to type 'undefined'. What is the best approach for dynamically assigning optional properties?

I am currently working on defining an interface named ParsedArguments to assign properties to an object, and here is what it looks like: import {Rules} from "../Rules/types/Rules"; export interface ParsedArguments { //other props //... ...

Retrieve a div element using Ajax from the result of an If statement

I need to extract a specific div from the data returned by an if statement that is formatted as HTML, and then display it within another div. I have been attempting to achieve this using the code below, but so far it has not been successful... Here is my ...

Navigate back to the previous route within the Vue router hierarchy

In my Vue application, I have a Settings page with child routes such as settings/user, settings/addUser, etc. I am looking to implement a back button that when pressed, takes the user back to the specific page they visited within the Settings section. Usin ...

What could be causing vertices in Three.js to not update?

I currently have a loop of circles that are moving independently. My goal is to draw lines from the center of the canvas to each circle's location. The issue I am facing is that the lines are not updating their vertices correctly during rendering, eve ...

Display navigation bar upon touch or lift

In the mobile version of a website, there is a fixed navigation bar at the top. The positioning of this navbar is achieved using position:absolute: .navbar-fixed-top{position:absolute;right:0;left:0;z-index:1000; The goal is to make the navbar invisible ...

Can you explain how the functionality of setState operates within React in this specific situation?

I've been working on updating the state of an object in my array. I managed to get it done, but I'm a bit confused about how it works. toggleVisited = countryCode => { var countries = [ ...this.state.countries ]; var countryToChange = c ...

Guide on converting arrays and sending this information in Node.js

I managed to retrieve quiz data and now I want to enhance it by mapping each answer to its respective quiz. I have a feeling that I should use something like forEach.push, but I haven't quite figured out the exact method... const API_KEY="https: ...

When using Javascript's querySelector, often times it returns null

Here is the HTML code I am working with: <button class="pop-btn"> Pop </button> While I was able to style this button using CSS, I encountered a problem when trying to select it in Javascript: const Population_div_Button=document. ...

The JSONP error code 414 states that the Request-URI is too large

My attempt to transmit a large amount of data (~50000 bytes) to another server using JSONP is resulting in a 414 (Request-URI Too Large) response because JSONP only allows GET requests. Splitting the data into 2k chunks significantly slows down the entire ...

Retrieve every potential option of a dropdown menu

One of my tasks involves working with a select field that has various values: africa europe america asia oceania Whenever a value is selected, I aim to apply a specific CSS class to a particular div, with the name of the CSS class matching the selected v ...