2

Below is an example of a JavaScript project in which a Description field goes into an edit mode when the edit button is clicked on. This reveals a hidden textarea, some tabs to switch between edit and preview markdown output, and save and cancel buttons are all revealed.

Once the description is saved or canceled which trigger it to "close" out of edit mode

Right now to get out of edit mode you have to click the save or cancel buttons in the image below.

I would like to auto-close when the user clicks outside of the edit mode sections. So a click anywhere that is not related to the edit mode would then fire my JavaScript code which "closes edit mode".

Something like....

If in edit mode{

    if click on any selector that is not .edit-btn, .save-btn, .tabs, or edit-wrapper{

        // call my close edit mode function
        closeEditMOde();

    }

}

All names and everything made up to quickly explain my goal.

How can I achieve this in JavaScript/jQuery?

Something clever like a simple utility function would be nice that took an array of selectors....

function ifAnyElemExceptTheseClickedOn(['.save-btn', '.cancel-btn', '#edit-wrapper', '.tabs']){

    // if a click event happens anywhere that is not inside one of the passed 
    // in array of selector elements on the page, then perform an action 

    // if click is outside of any of thewse selectors, then run a callback function

}

Clicking any of the red boxes will result in nothing besides there own defined click events.

Clicking anywhere outside the red boxes will trigger/fire function call to my JS function.

enter image description here


UPDATE

I now have a simple demo here http://jsfiddle.net/jasondavis/gpyusv6a/ which I think will work for my needs if I can get rid of the JS error that is thrown when I click outside of the DIVs which give this:

Uncaught TypeError: Cannot read property 'match' of undefined  

Demo:

<div id="edit-wrapper">edit mode section
    <div id="edit-wrapper-inner">
        edit mode inner section
    </div>
</div>

$(document).click(function(event) {
  var target = $(event.target);

  console.log(target);

  if (!target.attr('id').match(/^edit-wrapper/).length && target.parents('#edit-wrapper').length == 0) {
      console.log('Hide edit-wrapper because you clicked on the screen outside of the #edit-wrapper DIV');
      $('#edit-wrapper').hide();
  }
});
7
  • 1
    There's really nothing to go on here, no elements, example code, or anything? Anyway, it's quite easy, you attach an event handler to the document, and use a condition, something like if ( $(e.target).closest('#edit_box').length === 0 ) close_edit_box() Commented Oct 24, 2015 at 22:29
  • Attach a click handler to the <body> and leave edit mode if in edit mode and stop propagation, else let it propagate (?) Commented Oct 24, 2015 at 22:29
  • @adeneo I think I understand somewhat in this JSFiddle jsfiddle.net/jasondavis/gpyusv6a however whgen clickinmg outside of the DIVs I get this error: Uncaught TypeError: Cannot read property 'match' of undefined it's close to working though thanks Commented Oct 24, 2015 at 22:46
  • 1
    You're complicating it! closest() starts with the current element, so you don't need a regex or parents() -> jsfiddle.net/gpyusv6a/4 Commented Oct 24, 2015 at 22:54
  • @adeneo thanks jsfiddle.net/jasondavis/gpyusv6a/5 Ill just add some code to not fire when not in edit mode and this should work great now! Commented Oct 24, 2015 at 23:00

2 Answers 2

1

I think you need the :not selector

Example:

$(document.body).on('click','*:not(.edit-btn, .save-btn, .tabs, #edit-wrapper)', function(){
    YOUR CODE
});
Sign up to request clarification or add additional context in comments.

3 Comments

Quick demo of your method jsfiddle.net/jasondavis/Loy1z3vf/2 it seems that it gets fired when I click anywhere though
You should give a try and add a .dont-exit-edit-mode class or similar to all the controls you want to exclude from the click event, and use a more simple :not selector like *:not(.dont-exit-edit-mode)
Be definite! If you think but don't know maybe a comment would be better; but if this works, starting with I think... simply sounds unsure.
1

To catch a click anywhere, you can attatch an event handler to the document

$(document).on('click', function() {...

and then filter with a condition.
jQuery's closest() starts at the current element and traverses up through the parents until a match is found, so it's perfect for this kinda thing

$(document).on('click', function(event) {
    var target = $(event.target);

    if ( target.closest('#edit-wrapper').length === 0 ) {
        $('#edit-wrapper').hide();
    }

});

So if the clicked element (event.target) doesn't have a parent element matching the selector #edit-wrapper, or isn't in fact #edit-wrapper itself, it's an element outside the edit box, and the box should be hidden.

One could add more to the condition, for instance a boolean so the condition only fires when in "edit mode" etc.

if ( target.closest('#edit-wrapper').length === 0 && in_edit_mode) {

    // hide edit box

FIDDLE

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.