Is possiblle lock a background from a modal in Primefaces?
In example basic, when you scroll down all screen is move, except the dialog. But, I need lock the body because all my ponents inside of dialog are moving too with the body in background.
.xhtml
I'm using modal="true" but it's just change de color of the background.
Is possiblle lock a background from a modal in Primefaces?
In example basic, when you scroll down all screen is move, except the dialog. But, I need lock the body because all my ponents inside of dialog are moving too with the body in background.
http://www.primefaces/showcase/ui/overlay/dialog/basic.xhtml
I'm using modal="true" but it's just change de color of the background.
Share Improve this question asked Jun 4, 2014 at 20:53 Helio BentzenHelio Bentzen 6772 gold badges12 silver badges24 bronze badges6 Answers
Reset to default 2I have another solution, I define two javascript function
function ovBodyAuto(){
$('html, body').css('overflow', 'auto');
}
function ovBodyHidden(){
$('html, body').css('overflow', 'hidden');
}
and my primeface dialog looks like this
<p:dialog widgetVar="detail" showEffect="explode" width="1200" height="600"
modal="true" hideEffect="explode" onShow="ovBodyHidden();" onHide="ovBodyAuto();">
</p:dialog>
it may not look like an elegant way, but it works for me.
There is a more elegant way to do that, using @mismanc answer. There is no need to call onShow and onHide in every single dialog.
First of all, on Primefaces 5.3+ and 6.0, in layout.js, there is a script like the following:
if(window['PrimeFaces'] && window['PrimeFaces'].widget.Dialog) {
PrimeFaces.widget.Dialog = PrimeFaces.widget.Dialog.extend({
enableModality: function() {
this._super();
$(document.body).children(this.jqId + '_modal').addClass('ui-dialog-mask');
},
syncWindowResize: function() {}
});
}
Just add the code to set overflow hidden on enableModality and set the overflow auto on disableModality, like this:
if(window['PrimeFaces'] && window['PrimeFaces'].widget.Dialog) {
PrimeFaces.widget.Dialog = PrimeFaces.widget.Dialog.extend({
enableModality: function() {
this._super();
$(document.body).children(this.jqId + '_modal').addClass('ui-dialog-mask');
$('html, body').css('overflow', 'hidden');
},
disableModality: function() {
this._super();
$('html, body').css('overflow', 'auto');
},
syncWindowResize: function() {}
});
}
I found another solution to this problem in Primefaces 5.
I just make fixed all ponents that floating in screen when I scrolling.
So, I rewrite it:
.ui-selectonemenu-panel {
position: fixed !important;
}
.ui-selectcheckboxmenu-panel{
position: fixed !important;
}
I have scroll in backgroun yet, but all ponent when open is not floating.
You should use body{overflow:hidden;}
when your modal is visible
First you should make sure that your form
is outside the dialog
.
Then in order to prevent the background screen from scrolling while the dialog is opened, you should use some javascript on the opening and closing of the dialog, here's an example:
Javascript
/**
* Disable Scroll
* left: 37, up: 38, right: 39, down: 40,
* spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
*/
var scrollKeys = [ 37, 38, 39, 40 ];
function scrollPreventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function scrollKeydown(e) {
for ( var i = scrollKeys.length; i--;) {
if (e.keyCode === scrollKeys[i]) {
scrollPreventDefault(e);
return;
}
}
}
function sctollWheel(e) {
scrollPreventDefault(e);
}
/**
* This would be called on "onShow" in order to disable the background scrolling
*/
function disableScroll() {
if (window.addEventListener) {
window.addEventListener('DOMMouseScroll', sctollWheel, false);
}
window.onmousewheel = document.onmousewheel = sctollWheel;
document.onkeydown = scrollKeydown;
}
/**
* This would be called on "onHide" in order to enable the background scrolling
*/
function enableScroll() {
if (window.removeEventListener) {
window.removeEventListener('DOMMouseScroll', sctollWheel, false);
}
window.onmousewheel = document.onmousewheel = document.onkeydown = null;
}
/**
* End Disable Scroll
*/
Place the upper javascript code in an external js file and include it in your page, then:
XHTML
<p:lightBox onShow="disableScroll()" onHide="enableScroll()">
OR
<p:dialog onShow="disableScroll()" onHide="enableScroll()">
Hope this helps.
I had an issue whereby users would rather press the enter key on their keyboard than click the 'Confirm ' button in my modal. The form behind had entries for password and username and now the modal. When the user pressed the key on their keyboard, the whole form would be submitted instead of the action on the dialog(modal) button. If user however clicked the button, everything worked well. To fix this, I put my dialog in its form so that any action performed on it would not affect the form behind it. I feel this would fix for you too.
Below is my prime faces page:
<h:form id="mainform">
<p:panelGrid columns="1">
<p:panelGrid id="login" columns="2" styleClass="ui-noborder">
<p:outputLabel value="User Name: " for="user"/>
<p:inputText id="user" value="#{users.username}" required="true" requiredMessage="User name cannot be empty"/>
<p:outputLabel value="Password: " for="pass"/>
<p:password id="pass" value="#{users.password}" required="true" requiredMessage="Password cannot be empty"/>
</p:panelGrid>
<p:mandButton value="Login" action="#{users.login()}" style="width:70%;height:30%;align-content: center;" update="message" />
</p:panelGrid>
</div>
</h:form>
<h:form id="confirm">
<p:dialog id="otpdialog" header="Enter OTP" widgetVar="dlgotp" hideEffect="explode" >
<p:panelGrid columns="2" >
<h:outputLabel for="otp" value="Enter OTP sent to registered mobile number: "/>
<p:inputText id="otp" value="#{users.otp}" maxlength="7"/>
</p:panelGrid>
<br/>
<div align="center">
<p:mandButton action="#{users.confirmOTP()}" value="Confirm OTP" ajax="false"/>
</div>
</p:dialog>
</h:form>
Below is how I show the dialog on submitting the first form:
PrimeFaces.current().executeScript("PF('dlgotp').show();");