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 styleClassremoveTabHandlingFromPanel(#{rich:component('mp')});
So, finally solution is done and works fine within all the browsers supported with RichFaces.
Ilya, interesting post, thx for sharing!
do you mean rich:modalPanel rather than rich:panel above?
Have you guys started testing your components and solutions/tips like these using IE 8? I've noticed a lot of issues when using RF and IE (which is our corporate standard).
I would also suggest that tips like this need to be centralized in one repository/forum/wiki, etc. so it's easier for us RF/Seam developers to find and use them.
Hi!
yes :)
First IE8 testing started before 3.3.1 release after IE released. Now we continue our stabilization work in this direction.
Already working on that :) I mean new official page and more structurized wiki pages which will be more convinient to be used by the community and team both.
I'm creating the modalpanel dynamically in the bean, by calling the method from a a4j:commandLink, and calling removeTabHandlingFromPanel(modalPanelComponent) on the oncomplete event for this commandLink, but I'm having the same error described above. Is there any workaround on this?
The must be executed just after the rich:modalPanel. I am doing like that and works with no errors.
Congratulations for this post
I changed tag panel id="mp" minHeight="200" minWidth="450" styleClass="noMaskClass" height="200" width="500"
instead of modalPanel id="mp" minHeight="200" minWidth="450" styleClass="noMaskClass"
height="200" width="500"
please help me
Please any one help me!!!!!!!!!!
can you give the sample code of the above issue.
i am getting modelPanel.js not implemented error.
Hi Ilya,
Great post.
Fully working under FF 3 But not working under IE7
.noMaskClass .rich-mpnl-mask-div{ display:none; }
Indeed noMaskClass makes the modalPanel not visible at all. if you set .noMaskClass .rich-mpnl-mask-div-opaque{ display:none; } it is better under IE (at least the modal shows up), BUT is not working under FF anymore
do you think of a workaround for this... thanks
Found the solution fully working on FF and IE
Do not use noMaskClass and use the following function just after
#{rich:component('mpId')}.show();Function in script tag
function removeTabHandlingFromPanel(modalPanelId){ var modalPanelComponent = document.getElementById(modalPanelId).component; modalPanelComponent.lastOnfocus = function(event){return;}; modalPanelComponent.firstOnfocus = function(event){return;}; modalPanelComponent.processAllFocusElements = function(event){return;}; modalPanelComponent.processTabindexes = function(event){return;}; modalPanelComponent.restoreTabindexes = function(event){return;}; modalPanelComponent.preventFocus = function(event){return;}; modalPanelComponent.restoreFocus = function(event){return;}; document.getElementById(modalPanelId+'Div').style.display="none"; document.getElementById(modalPanelId+'CursorDiv').style.display="none"; }SO it ends to (mpId show be the clientId)
#{rich:component('mpId')}.show();removeTabHandlingFromPanel('mpId');regards and have a happy new year all
Can we apply onmaskclick event on non-modal panel??YneduW
Problem in IE6(i know, but stack with having to support it)...select lists get disabled after the non-modal panel as described is shown...
Also, using the attribute causes the js error in IE6 if the destination component is disabled...generated JS code should have just caught and ignored the error...this poses a big problem when trying to use invisible modal panel on an ajax request, causing the select list to became disabled temporarily, but focus executes before the modal panel is released, causing JS error in IE6...just plain discouraging and dissapointing behaviour.