Detecting a click outside an element

Hi :wave:,

I am creating a filter selector like so:
ezgif.com-video-to-gif

I created this using the hover dropdown element, but I’ve ran into a blocker.
I am trying to close the dropdown when the ‘save’ button is pressed, but the element only allows for closing the element on any click or only clicks outside of the element - so not a specific click inside the element.

Is there any way I can manually detect a click outside of the hover dropdown (or any element)?
I could then use this in a manual workflow to bind the display.

Also, do I need to do something specific for the hover dropdown display animations to work?
It seems just to be displaying instantly with no animation, regardless of the animation or duration I set.

Thanks! :slight_smile:

After looking through the Github of the element, I noticed the function handleClickOutside(), but I’m not sure how/if I could call this from the browser?

If you arent tied to using hover, On Click will help you accomplish that. If On Hover is a requirement though, someone else may have a better approach.

I’ll need to bind the display of the element if I use On Click.
At the moment I’m using the element’s native functionality for hiding/displaying.

Once I bind the display, I’ll need some way to correctly hide the element if someone clicks outside it. That’s my crux at the moment.

You could add a bit of javascript that binds the blur event to toggle the variable that controls your element. So assuming you give it an ID of “myelement,” and display is bound to a variable called “show_myelement” you could set up an action (running on, say, page load) with the javascript:

wwLib.getFrontDocument().querySelector('#myelement').addEventListener('blur', function(event) {
  wwLib.wwVariable.updateVariable('show_myelement', false); 
})

This kind of “bring a little code” is what makes lowcode so powerful!

3 Likes

I do this in my app:

Add a div where I want the drop-down
Add the trigger, popup, and another div I call backdrop

Set your trigger to look how it should,

Set your drop-down to a fixed position and use translate to move it where it needs to be. Set the z-index to 100

Set your backdrop to z-index 99x set position to fixed. Set the left right top and bottom values to 0 pix. Just to be safe, set the height and width to 100%

Use a variable to show the drop-down. Bind the drop-down and backdrop to that variable so they both show at the same time.

Now you can use the backdrop to “listen” for the click event off of the drop-down.

5 Likes

Amazing!

Thanks guys @raydeck @jaredgibb

1 Like

Does this work with a container? I’ve set this JS code as a workflow action to run on page load. But when I try to click outside of the container, it is still being shown.

The code I’m using:

wwLib.getFrontDocument().querySelector('#selector-container').addEventListener('blur', function(event) {
  wwLib.wwVariable.updateVariable('showSearchableDropdown', false); 
})

If anyone else happens to stumble on this, I solved it with this code.

wwLib.getFrontWindow().addEventListener('click', function(e){   

  if (!wwLib.getFrontDocument().getElementById('your-element').contains(e.target)){
  // If your element (with an id #your-element) doesn't contain the click event's target (e.target) execute this

  variables['a43f9f7f-3248-4ab4-995f-47018ce388fe'] = false
  // [your_visibility_variable] = false

  } 
});
1 Like

Hi,
I’ve tried both code snippets suggested in this thread and none of them works. I have a component that contains an element that is revealed on click event. I hide it by using conditional rendering where the rendering is binded to global boolean variable tooltipVisibility. Now, I am able to show an element (it is triggered by clicking another element within that component, that switches the boolean to true). But when it comes to hiding it by clicking outside the element, above code snippet suggested by @raelyn throws such error:

name: "TypeError"

stack: "TypeError: Cannot read properties of null (reading 'addEventListener') at eval (eval at executeCode (https://editor-cdn.weweb.io/ww_front/public/js/index.697ae9af.js:1:370508), :1:84) at eval (eval at executeCode (https://editor-cdn.weweb.io/ww_front/public/js/index.697ae9af.js:1:370508), :4:3) at executeCode (https://editor-cdn.weweb.io/ww_front/public/js/index.697ae9af.js:1:370508) at we (https://editor-cdn.weweb.io/ww_front/public/js/index.697ae9af.js:1:444020) at me (https://editor-cdn.weweb.io/ww_front/public/js/index.697ae9af.js:1:442395) at pe (https://editor-cdn.weweb.io/ww_front/public/js/index.697ae9af.js:1:440924) at https://editor-cdn.weweb.io/ww_front/public/js/index.697ae9af.js:1:458574 at Array.map () at ge (https://editor-cdn.weweb.io/ww_front/public/js/index.697ae9af.js:1:458566) at _e (https://editor-cdn.weweb.io/ww_front/public/js/index.697ae9af.js:1:461420)"

message: "Cannot read properties of null (reading 'addEventListener')"

and a code snippet suggested by @Broberto seems to have some effect, because I see this message in the log:

Setting value for tooltipVisibility

but nothing happens. As a matter of fact, when the code snippet is activated I am neither able to show nor hide the tooltip…

Not 100% sure, if I understand you correctly, but I think it’s because you use conditional rendering for hiding. This way, the element is completely removed from the page, which ends up being null. So try showing/hiding your element by binding tooltipVisibility to the display property. Does that help?

This is still the case. Changing animation settings don’t have any effect. I guess that’s a job for @aurelie?

Hi @andreas, thanks for the suggestion, but it turned out that @Broberto 's solution worked, but I had to reassign the required element ID to some other element (to an outer wrapper that contained a tooltip as well as element revealing the tooltip on click). Now everything works.

1 Like

Great. Glad you solved this.

@maciej.ziolkowski and everyone else thanks for this code snippet / discussion, it’s very useful and it worked when testing for me. However, I have a slight variation of the use-case which I can’t figure out.

Per the screenshot, the items (Start. Welcome, Onboarding) are in a dynamic and nested collection list.

At each item level, the three horizontal dots open the menu (add and delete flow) when one of the items is clicked, the menu is removed. This is working fine, I’m changing “menu_visible”: true/false in the collection list.

As per the discussion, the problem I have is when you click outside of the menu, it doesn’t close and if you click on the three dots against another item you end up with a mess.

I tried @maciej.ziolkowski code and it works but I end up with a different problem. The event handler sets “menu_visible”: false but because the event handler now persists, subsequent clicks on the three dots no longer work as each click negates “menu_visible”: true.

What I’m thinking is the event handler to only persist whilst the menu is visible, then it should be removed until it’s created next time.

Any ideas how to do this?

Ideally there would be a On Blur event for divs, similar to text fields, which would solve this.

BTW, I was originally using the Dropdown element but this has it’s own display issues, when it’s used in a collection list, the menu displays under the trigger button of other items in the list. I prefer the more “manual” approach anyway.

Hi @Dom. Unfortunately I am unable to help you. I am new to the low-code game :slight_smile: and still have a lot to learn.