Requirements: When user presses the ESC key, a dialog should be closed. When user presses the ENTER key, the dialog action should be submitted (imagine e.g. a "Are you sure you want to delete?" dialog). Dialog can look like as follows. In the real world it is better to please the dialog into a composite component in order to reuse it.
<p:confirmDialog header="Confirmation" widgetVar="confirmDlgWidget" appendToBody="true"> <f:facet name="message"> ... </f:facet> <h:form> <p:commandButton value="OK" process="@this" update="..." action="..." oncomplete="confirmDlgWidget.hide();"/> <p:commandButton value="Cancel" onclick="confirmDlgWidget.hide();" type="button"/> </h:form> </p:confirmDialog>After the dialog tag, the following short JS script should be placed.
<script type="text/javascript"> /* <![CDATA[ */ $(function () { registerConfirmDialogHotkeys(confirmDlgWidget); }); /* ]]> */ </script>The JS function itself is located in a file. Here how it was implemented:
function registerConfirmDialogHotkeys(dlgWidget) { var key = 'keydown.pfdialog_' + dlgWidget.id; $(document).off(key).on(key, function (e) { var keyCode = $.ui.keyCode; var active = parseInt(dlgWidget.jq.css('z-index')) === PrimeFaces.zindex; if (dlgWidget.jq.hasClass('ui-overlay-visible') && active) { if (e.which === keyCode.ESCAPE) { dlgWidget.hide(); } else if (e.which === keyCode.ENTER || e.which == keyCode.NUMPAD_ENTER) { dlgWidget.jq.find('button:submit:first').click(); e.preventDefault(); } } }); }The function registers a namespaced keydown JS callback on document. The callback checks if the dialog is active currently. This is normally a last opened dialog. If it is active and the user has pressed ESC, then hide the dialog (widget variable is passed into the function). If it is active and the user has pressed ENTER, then find the first submit button within this dialog and click it to cause an action execution. That's all.
This is very good & useful blog i am regular reader of your blog, thanks for posting wonderful article
ReplyDeleteHow can I fix this to work on Primefaces 5.2?
ReplyDeleteIt's not working on prime 5.2, do you have any idea how could I fix? thanks
ReplyDeleteThanks for testing it on PF 5.2. I have found the issue. You have to replace
DeletedlgWidget.jq.hasClass('ui-overlay-visible')
by
dlgWidget.jq.is(':visible')
and it starts to work again!
Thank you very much for your amazing work =)
ReplyDelete