How to add form loaded close on moseup/click outside of form loaded?

Sorry for the long winded title. I want to be a little clearer here. The below JS code acts as a toggle to open/display a container on toggle. I need for this code to be extended so that it forces the container to close if a mouse click is placed outside of the loaded form.

the following html passes id of form to load

<span id="lr-action"><a href="#" onclick="toggle_visibility('lr-form');"><h4>Sign In / Register</h4></a></span>

function toggle_visibility(id) {
       var e = document.getElementById(id);
       if(e.style.display == 'block')
          e.style.display = 'none';
       else
          e.style.display = 'block';
};

All is good. Toggle works fine. But how can I add a close form function if mouse click happens outside of form loaded?

Have tried adding a snippet for this, but faced the problem of toggle close not working while click out of form working (if that makes sense!)

Thanks in advance

x

You could detect if the HTML element gets clicked maybe?

Also just realized, even if my above suggestion didn’t work…when you click something to open it, that element must have a :focus on it, correct? Detect when that element loses focus.

Hi,

I’m guessing that you might be using this function elsewhere in your code, due to its generic nature, so we’ll not mess with the function itself.

Instead, as @RyanReese suggested above, we can bind a new event listener to the document and use that to manage shutting the form.

Before we get to the code, please note that the code you posted will not validate and produces this error:

Element h4 not allowed as child of element a in this context.

Maybe you want to think about losing the heading tags, or moving them?

Also, try not to use inline event handlers. They are messy and hard to maintain.

That said, this would leave us with:

function isDescendant(parent, child) {
     var node = child.parentNode;
     while (node !== null) {
         if (node == parent) {
             return true;
         }
         node = node.parentNode;
     }
     return false;
}

function toggle_visibility(id) {
  var e = document.getElementById(id);
    if(e.style.display == 'block'){
      e.style.display = 'none';
    } else {
      e.style.display = 'block';
    }
}

var link = document.getElementsByTagName("a")[0],
    form= document.getElementById("lr-form");

link.addEventListener('click', function(e){
    toggle_visibility('lr-form');
    e.stopPropagation();
});

document.addEventListener('click', function(e){
    if(isDescendant(form, e.target) || e.target.id === "lr-form" || form.style.display === 'none'){
      return;
    }
    toggle_visibility('lr-form');
});

Here’s a demo

I’ve made it so that the form is big and red, so that you see that its visibility is not altered if you click inside it.

If you have any questions, just let me know.

Sorry for the delat chaps and thanks so much for your replies. After hours and hours of work, this login method wasn’t liked by a partner. So it was unfortunately scrapped. But yes Pullo, this jq event is being used in other places where your code will definitely help.

Thanks again