Forums

angle-left Back

[SOLVED] Liferay Faces prevent escape key in modal/dialog

DG
Damien Guillermet, modified 10 Months ago.

[SOLVED] Liferay Faces prevent escape key in modal/dialog

Junior Member Posts: 42 Join Date: 7/9/15 Recent Posts
Hello,

I'm using Liferay Faces Alloy 3.0.0 and for a best user experience I would like to prevent client escape key event to close the dialog box. At least, display a confirm box in order to prevent loosing all data entered in form contained in dialog box.

So I tried to achieve this using the dialog's onkeydown attribute like:
<alloy:dialog clientKey="myDialog" headerText="My Dialog" modal="true" hideIconRendered="false" dismissible="false" onkeydown="preventDefaultEscapeKeyHandler(event)">
    <alloy:form>
        <!-- Something. -->
    </alloy:form>
</alloy:dialog>


With JS function as:
function preventDefaultEscapeKeyHandler(event) {
    if (event.keyCode === 27) {
        console.log('Prevent default escape key.');
        event.preventDefault();
    }
}


The function is called as expected but that does not prevent the dialog to be closed.
Furthermore if a modal is opened behind the one with the prevent escape key function then all modals are closed. So if there is a way to prevent escape key everywhere (not only inside modals) I'm interested too.

Anybody has an idea to achieve this goal ?

Best regards.
Damien.
Kyle Joseph Stiemann, modified 10 Months ago.

RE: Liferay Faces prevent escape key in modal/dialog

LIFERAY STAFF Liferay Master Posts: 659 Join Date: 1/14/13 Recent Posts
Hi Damien,
alloy:dialog uses AlloyUI Modal under the hood, so you can use the same method as my answer for AlloyUI Modal:

<alloy:outputScript use="aui-modal,event-key" target="body">
A.one('body').on('key', function(event) {
Liferay.component('myDialog').once('visibleChange', function(event) {
// If the dialog was already visible, then keep it visible.
if (event.prevVal === true) {
event.newVal = true;
}
});
}, 'esc');
</alloy:outputScript>


The above code attaches a one-time visibleChange listener to the dialog each time ESC is pressed that ensures it will remain visible after ESC is pressed. Otherwise, the dialog can be hidden normally.

- Kyle
DG
Damien Guillermet, modified 10 Months ago.

RE: Liferay Faces prevent escape key in modal/dialog

Junior Member Posts: 42 Join Date: 7/9/15 Recent Posts
Hello Kyle,

Firstly sorry because I should try to search on Liferay forum for a similar answer.
Now I tried your code and it works well thank you very much.

By the way if I have 10 modals I have to add this script 10 times. I guess there is no way to factorise this?

Regards,
Damien.
Kyle Joseph Stiemann, modified 10 Months ago.

RE: Liferay Faces prevent escape key in modal/dialog

LIFERAY STAFF Liferay Master Posts: 659 Join Date: 1/14/13 Recent Posts
Hi Damien,
No need to apologize! I actually had a pretty hard time finding that old answer, so I wouldn't expect anyone else to find it emoticon.

I think you should be able to use a for loop to make this work for multiple dialogs:

<alloy:outputScript use="aui-modal,event-key" target="body">// <![CDATA[
var dialogClientKeys = ['dialogKey1', 'dialogKey2', 'dialogKey3'];

A.one('body').on('key', function(event) {

for (var i = 0; i < dialogClientKeys.length; i++) {
var dialog = Liferay.component(dialogClientKeys[i]);

if (dialog.get('visible')) {

dialog.once('visibleChange', function(event) {
// If the dialog was already visible, then keep it visible.
if (event.prevVal === true) {
event.newVal = true;
}
});
}
}
}, 'esc');
/* ]]> */</alloy:outputScript>


You could also programmatically search the view for alloy:dialog components and obtain their client keys if you really didn't want to write them twice (var dialogClientKeys = [#{bean.dialogClientKeys}];), but that seems like overkill unless you need generic code for many views.

- Kyle
DG
Damien Guillermet, modified 10 Months ago.

RE: Liferay Faces prevent escape key in modal/dialog

Junior Member Posts: 42 Join Date: 7/9/15 Recent Posts
Storing dialog client keys in an array, nice idea! Well I just have to be sure that all dialogs are in the same naming container as the script.
I will try your solution. Again, thank you very much emoticon

Damien.