Created by @vylink in Q&As
@vylink
@vylink

Hi,

how to implement (extend) dialog behaviour to be closable by keyboard key(esc), or by click outside?

Thanks,

M

@jahudka
@jahudka

Hi,

closing on Esc is already possible with the nittro-extras-keymap package. If you just install that and enable it in your builder, closing by Escape should Just Work without any further configuration. You can also customise this behaviour using the keyMap option.

To close the dialog when clicking outside you can overload the _handleClick() method. This is a delegated listener for all click events anywhere in the root dialog element (which, incidentally, is the backdrop, or outside area, of the dialog). You could do something like this:

_context.invoke(function(Dialog) {
    var originalHandler = Dialog.prototype._handleClick;

    Dialog.prototype._handleClick = function(evt) {
        if (evt.target === this._.elms.holder) {
            evt.preventDefault();
            this.hide();
        } else {
            originalHandler.call(this, evt);
        }
    };
}, { Dialog: 'Nittro.Dialogs.Dialog' });
@vasek
@vasek

Hi,

I tried the proposed solution, but the _handleClick() method is executed only for click events on the dialog content itself; not on the backdrop. Did the behavior change since then?

@vasek
@vasek

Ok, I've found that the _handleClick() method is connected to this._.elms.wrapper and not this._.elms.holder.

I solved it this way for now:

_context.invoke(function (DOM, Dialog) {

    Dialog.prototype._holderClick = function (evt) {
        if (evt.target === this._.elms.holder) {
            evt.preventDefault();
            this.hide();
        }
    };

    var originalShow = Dialog.prototype.show;
    Dialog.prototype.show = function () {
        DOM.addListener(this._.elms.holder, 'click', this._holderClick.bind(this));
        return originalShow.call(this);
    };

    var originalHide = Dialog.prototype.hide;
    Dialog.prototype.hide = function () {
        DOM.removeListener(this._.elms.holder, 'click', this._holderClick.bind(this));
        return originalHide.call(this);
    };

}, {DOM: 'Utils.DOM', Dialog: 'Nittro.Extras.Dialogs.Dialog'});
@jahudka
@jahudka

Hi, sorry, my bad, I thought the handler is bound on the backdrop.. I'll fix that :-) till then your implementation will work, but you should forward the return values from originalShow and originalHide, because these are Promises if I'm not mistaken and other code might depend on them.

@vasek
@vasek

Ok, thanks :) You're right about the return values, I'll forward them. Thanks for pointing that out.

Sign in to post a reply