是否可以从 Primefaces 中的模态锁定背景?
在基本示例中,当您向下滚动时,除对话框之外的所有屏幕都会移动。但是,我需要锁定主体,因为对话框内的所有组件也随着主体在后台移动。
http://www.primefaces.org/showcase/ui/overlay/dialog/basic.xhtml
我正在使用 modal="true" 但它只是改变背景的颜色。
我有另一个解决方案,我定义了两个javascript函数
function ovBodyAuto(){
$('html, body').css('overflow', 'auto');
}
function ovBodyHidden(){
$('html, body').css('overflow', 'hidden');
}
我的 primeface 对话框看起来像这样
<p:dialog widgetVar="detail" showEffect="explode" width="1200" height="600"
modal="true" hideEffect="explode" onShow="ovBodyHidden();" onHide="ovBodyAuto();">
</p:dialog>
它可能看起来不是一种优雅的方式,但它对我有用。
有一种更优雅的方法可以做到这一点,使用@mismanc 答案。 无需在每个对话框中调用 onShow 和 onHide。
首先,在Primefaces 5.3+和6.0上,在layout.js中,有一个如下的脚本:
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() {}
});
}
只需添加代码在 enableModality 上设置溢出 hidden 并在 disableModality 上设置溢出 auto,如下所示:
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() {}
});
}
我在 Primefaces 5 中找到了解决此问题的另一种方法。
我只是修复了滚动时漂浮在屏幕上的所有组件。
所以,我重写它:
.ui-selectonemenu-panel {
position: fixed !important;
}
.ui-selectcheckboxmenu-panel{
position: fixed !important;
}
我已经在背景中滚动了,但是打开时所有组件都不是浮动的。
当您的模态框可见时,您应该使用
body{overflow:hidden;}
首先您应该确保您的
form
位于 dialog
之外。
那么为了防止对话框打开时背景屏幕滚动,您应该在对话框的打开和关闭上使用一些javascript,下面是一个示例:
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
*/
将上面的 javascript 代码放在外部 js 文件中并将其包含在您的页面中,然后:
XHTML
<p:lightBox onShow="disableScroll()" onHide="enableScroll()">
或
<p:dialog onShow="disableScroll()" onHide="enableScroll()">
希望这有帮助。
我遇到一个问题,用户宁愿按键盘上的 Enter 键,也不愿单击模式中的“确认”按钮。后面的表单包含密码和用户名条目,现在是模式。当用户按下键盘上的键时,整个表单将被提交。为了解决这个问题,我将对话框放入其表单中,以便对其执行的任何操作都不会影响其后面的表单。我觉得这也适合你。
以下是我的主要面孔页面:
<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:commandButton 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:commandButton action="#{users.confirmOTP()}" value="Confirm OTP" ajax="false"/>
</div>
</p:dialog>
</h:form>
以下是我如何显示提交第一个表单的对话框:
PrimeFaces.current().executeScript("PF('dlgotp').show();");