The best place to ask programming/development questions, imo. UPDATE: stackoverflow is the *worst* place to *ask* questions (if your first question/comment doesn't get any up-rating/response, then u can't ask anymore questions--ridiculously unrealistic), but a great reference for finding answers.

My Music (Nickleus)

20130924

richfaces how to close rich:modalPanel with escape key rich:hotKey, including modalpanels that open other modalpanels (multi-tier/multi-level)

the following code works both for single modal panels AND for multi-level modal panels (modal panels that open new modal panels, i.e. more than one modal panel open at the same time/on top of each other).

note: all rich:modalPanel tags must have a unique id attribute.

note: for some reason (1, 2), at least in our company's app, you have click the modal panel and then press escape in order for the "hide" functionality to work, so if anyone has a solution to this, i'd love to hear it. i tried generating a javascript click() event on the modalpanel to set focus to it, but it didn't help/work. but, despite that, it's still better and faster than having to mouse up to the "x" (close) icon or down to the cancel button at the bottom :)



scripts/keyboard-controls.js

...
var ActiveModal = new function() {
    this.visiblePanelIDs = new Array();
    this.activeModalPanel = null;
    this.removeModal = function(a) {
        if(a && (a != "wait")) {
            this.visiblePanelIDs.splice(0,1);
            this.activeModalPanel = this.visiblePanelIDs[0];
        }
    };
    this.addModal = function(a) {
        if(a && (a != "wait")) {

            a = a.id.replace(/Container/,'');
            this.visiblePanelIDs.splice(0,0,a);
            this.activeModalPanel = this.visiblePanelIDs[0];
        }
    };
};

...


explanation of a = a.id.replace(/Container/,''); :
gets the actual modalPanel id by stripping away the richfaces-appended text "Container" on the rendered id

the JSON code above is based on Justin Skinner's Multiple RichFaces Modal with Same Shortcut Key to Close. my improvement is that the code now works with multi-level modalpanels--it works with an array of modalpanel ids.

every time a new modalpanel is opened, its id is placed at the beginning of the array and "older" panels (that are still open) get pushed further back in the array so that when you close the modalpanel on top, the code simply removes the id at the front of the array--index 0 (zero).

e.g.:
open modalpanel1
visiblePanelIDs: {"modalpanel1"}
activeModalPanel: modalpanel1

open modalpanel2
visiblePanelIDs: {"modalpanel2","modalpanel1"}
activeModalPanel: modalpanel2

close modalpanel2
visiblePanelIDs: {"modalpanel1"}
activeModalPanel: modalpanel1

activeModalPanel is the modalpanel id that will get closed when you press the escape key

explanation of if(a && (a != "wait")):

during my testing of the code, i found out that the functions removeModal and addModal get run, no matter what, the first time ActiveModal gets initialized, and the "a" parameter is undefined (nothing). also, sometimes during processing, the parameter in to the functions has the value "wait". so, i don't want to do anything in the functions unless the parameter exists AND it isn't equal to "wait".



template code (or at the top of your xhtml/jsf page)

...
<script type="text/javascript" src="/scripts/keyboard-controls.js"></script>
</head>

<body>
...

<rich:hotKey key="esc" handler="if(ActiveModal.activeModalPanel){Richfaces.hideModalPanel(ActiveModal.activeModalPanel);}"/>
...



rich:modalPanel attributes onshow and onhide

<rich:modalPanel onshow="ActiveModal.addModal(this)" onhide="ActiveModal.removeModal('x')" id="transportAgreementDetails">


explanation of ActiveModal.removeModal('x'):

the parameter ('x') can be anything you want because the removeModal function simply removes the modal panel id at the beginning of the array (index 0), but we need some kind of text string sent in so we know that the function was called by the user and that it wasn't called during initialization of the ActiveModal object AND that it isn't a "wait" (see my explanation above).

No comments:

Post a Comment