1

Here is something I am trying to do. I have created a jsfiddle so you can look and let me know how to do what I am looking for.

$(document).ready(function() {
  $('#trigger-button').click( function () {
      $('#trigger-box').toggle();
  });
});

http://jsfiddle.net/s2FzE/

It's working fine as far as code is concerned. Clicking on button triggers a box to appear and disappear. Works fine.

But what I want is if someone click button and box appear then the box can disappear by 2 methods.

  1. clicking again on button or
  2. click anywhere except box (clicking on page body) <-- this is where i need help.
3
  • 1
    First of all, get rid of the second argument/function passed to click. It makes no sense. After that, have a look at jQuery UI dialogs. They probably do what you want. There are also tons of similar libs to show modal dialog windows. Commented Jul 25, 2013 at 9:05
  • Thanks changed. Yes second argument was not doing anything since I am using toggle. :) but I still need a simplest way to do second part. I don't want to use a large library to accomplish that. Commented Jul 25, 2013 at 9:09
  • There are small ones, too. malsup.com/jquery/block for example. However, if you do not want modal behavior see adeneo's answer. Commented Jul 25, 2013 at 9:13

2 Answers 2

2

here's my approach:

you need a document event listener to hide the box when user clicks anywhere. But the event listener is not necessary when box is hidden, so - it can be only added when box is shown, e.g.:

var box = $('#trigger-box'),
    showBox = function  (e) {
        if (!box.is(':visible')) {                      // only do that when box is hidden
            e.stopPropagation();                        // required to prevent document 
            box.show();
            $(document).on('click.showBox', hideBox);   // event namescope for easy removal
        }
    },

then - when the box is hiding - we can remove this event listener, like so:

var hideBox = function (e) {
    var target = $(e.target);
    if (target.is(box) || target.closest(box).length) return;  // don't close if clicked on box or on anything inside the box
    $(document).off('click.showBox');
    box.hide();
}

and then - we can just add the event listener:

 $('#trigger-button').on('click', showBox);

DEMO

Sign up to request clarification or add additional context in comments.

5 Comments

I don't get it, you got two upvotes, but why would you add an event handler inside another event handler and then use off(), and for me it doesn't work at all, clicking the box, it dissapears, and clicking the button twice, it doesn't dissapear? Maybe I misunderstood the question !
looks interesting but clicking trigger button is calling show box event and it does not hide box on clicking again. is that right.
@adeneo the event handler on document is added only when it's needed (when the box is visible), so it is not called every time you click on the page. The click-on-the-button-to-hide-box works now.
@tborychowski still not working, as suggested by adeneo, clicking box should not make it disappear.
@Roberthue sorry, I missed that. It's fixed now.
1

Listen for a click on the document level, and filter out any clicks on the button or box :

$(document).ready(function () {
    $('#trigger-button').click(function () {
        $('#trigger-box').toggle();
    });
    $(document).on('click', function(e) {
        if ( !$(e.target).closest('#trigger-box, #trigger-button').length ) 
             $('#trigger-box').hide();
    });
});

FIDDLE

5 Comments

Instead of the e.target check you can simply add a click handler on the outermost element of the dialog and call e.stopPropagation() to prevent the event from reaching the handler you added to the document itself. That removes the need to check for each item inside the dialog separately.
@ThiefMaster - yes, but the button and the box are siblings, so that means either stopping the propagation on both or on the containing element, #container, which sounds like an element that would contain more elements, and stopping the propagation on that could cause issues, so just checking the target seemed more appropriate.
Hm, why would you ever want to propagate a click event within a dialog to the outside world?
Yes, there will be other elements on page. usual html/css elements, forms and some custom javascript. And I don't want this to affect any other actions.
@adeneo can you expain what exactly are you checking with "if ( !$(e.target).closest('#trigger-box, #trigger-button').length )".

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.