2

I have defined an event handler for some elements on the page.

var selector = "div, select, input, button";
$(selector).on('click', function (e) {
    //deactivate function of the elements and prevent propagation
    e.preventDefault();
    e.stopPropagation();
    //...
    //dialog is loaded and created here
    //e.g. $(body).append('<see-dialog-html-from-below>');
    //...
    alert('selector click');
}

I then add (and remove) a dialog to the DOM at runtime (one dialog at a time). A simplified dialog could look like this:

<div id="dialog" class="ui vertical menu">
    <div class="item">
        <label for="constraints">Constraints:</label>
        <select id="constraints" name="constraints">
            <option value="0">option 0</option>
            <option value="1">option 1</option>
            <option value="2">option 2</option>
            <option value="3">option 3</option>
        </select>
    </div>
    <div class="item clearfix">
            <div class="ui buttons">
              <div id="save_button" class="ui green button">Save</div>
              <div class="or"></div>
              <div id="cancel_button" class="closebutton ui button">Cancel</div>
            </div>
    </div>
</div>

I bind more click actions to the cancel and save buttons when I create the dialog.

The problem is the select box. It triggers the first click event that I defined above.

How can I exclude all elements in the dialog box from being included in the first event handler?

7
  • If you want to exclude the select just remove it from the selector variable. Commented Jun 13, 2015 at 20:56
  • You could make sure the element is not a descendant of #dialog or possibly depending on your markup use > to limit the selector to direct children of some element (hard to say without seeing the all markup) Or something like *:not(#dialog) select and so on as selectors. Commented Jun 13, 2015 at 20:58
  • Look at the target -> if (e.target.hasClass()) or something alike Commented Jun 13, 2015 at 20:59
  • @EricMartinez: I cannot exclude the selector. And there could also be other elements in the dialog that will get targeted with the click event handler (like buttons and div containers). Commented Jun 13, 2015 at 21:12
  • @Mikey: Looking at the classes would require checking each child element of the dialog. I could add a class to each element of the dialog in its template and exclude it when I create the click event. But that would introduce another dependency into the application (which would be defficult to maintain and easy to forget). Commented Jun 13, 2015 at 21:20

2 Answers 2

5

If clicking the select triggers the alert, in the first event handler, then the dialog already exists in the page by the time you execute $(selector).on('click', ...). In that case you can exclude some elements from the selector with not.

$(selector).not('#dialog').on('click', ...)

This will bind a click handler to all elements matched by the selector but excluding elements matched in the not. If you have several dialogs consider using a CSS class like ui-dialog and using not('.ui-dialog').

EDIT: But note that if your dialog is placed inside a div and you do not stop the propagation of the custom events then any click in the popup will bubble up and also trigger the handler in the parent div. Just ensure you use e.stopPropagation(); when adding handlers to the dialog actions.

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

3 Comments

No, it does not exist. I load the dialog's template asynchronously (and store it), but the element is created and destroyed at runtime. As far as I understand, jQuery's 'on' replaced the 'live' method that was previously used. Which means it will trigger on dynamically added content. I did try your suggestion and the alert was triggered regardless.
Hmmm, and I cannot do something like this: $(selector + ' :not(#dialog)'). The selector has multiple parts, so the :not() would only apply to the last part...
I was not able to replicate your behavior until I figured you place the popup inside a div. So it's a matter of event propagation and I'll update my answer.
0

I have solved this for now by adding a click event handler for all elements of the dialog like so:

$('#dialog > ' + selector).on('click', function (e) {
    e.stopPropagation(); //prevent the event from bubbling through the DOM hierarchy
});

If you know a solution how I could exclude the dialog at the time of creation of the handler, please let me know.

1 Comment

You're over complicating things. Instead of using 'select' as the selector, use a class that select inputs inside dialogs wouldn't have. Or on the contrary, make sure that select inputs inside dialogs use a class that you would exclude with jquery's not selector.

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.