Draggable RichFaces panel or non-Modal Panel

Posted by    |      

Today I'd like to post a really simple solution which is frequently asked at RichFaces Users forum threads. Two questions which can be solved by using this solution:

  • Can the RichFaces popup component be non-modal?
  • Can the rich:panel component be draggable/resizable?

As you can guess I'll use the rich:modalPanel component in order to answer both questions, and the solution is really simple and relies on RichFaces special rich css classes.

Standard Modal Panel look and feel

At first we should open RichFaces developer guide and look to the modal panel skinability section. There we could find the rich-mpnl-mask-div style class which is applied to the page blocking div element for all the modal panels.

Now we can just to add

styleClass="noMaskClass"
to the rich:modalPanel component that we want to be non-modal. And then add the next simple css selector to the stylesheet used by the page:
.noMaskClass .rich-mpnl-mask-div{
    display:none;
}
So the richfaces-demo Modal Panel sample (second one) code changed to:
<style>
    .noMaskClass .rich-mpnl-mask-div{
        display:none;
    }
</style>
<rich:modalPanel  id="mp" minHeight="200" minWidth="450" styleClass="noMaskClass"
    height="200" width="500">
        //Panel Content
</rich:modalPanel>
Modal Panel with removed page blocking div

And if as a result panel in first sample opens as modal, and panel in second sample opens as non modal. So we have the panel with the resizability, autosize, moving, show/hide API and so on features..

So far so good.. But after simple tests we could see that this code works fine in all browsers in Windows environment except IE (Js error appears) and typing restricted in the parent page inputs in FF at linux environment.

After short investigation I found that that forgot about the modal panel client side methods which gets invoked in order to control the focus and tabbing. (accessing the parent page controls using tab control gets restricted using the methods.) But we not need these methods to be invoked at all if our panel is non-modal. So we should just override the methods with empty ones in order to get it working fine.

This is code of the function which will get the modal panel JS object and override needed methods:

function removeTabHandlingFromPanel(modalPanelComponent){
     modalPanelComponent.lastOnfocus = function(event){};
     modalPanelComponent.firstOnfocus = function(event){};
     modalPanelComponent.processAllFocusElements = function(event){};
     modalPanelComponent.processTabindexes = function(event){};
     modalPanelComponent.restoreTabindexes = function(event){};
     modalPanelComponent.preventFocus = function(event){};
     modalPanelComponent.restoreFocus = function(event){};
}
And now we will call this function for the panel which marked as non modal with noMask styleClass
removeTabHandlingFromPanel(#{rich:component('mp')});
So, finally solution is done and works fine within all the browsers supported with RichFaces.

Back to top