PrimeFaces 确认对话框中的倒计时器

问题描述 投票:0回答:2

在我的 Web 应用程序中,我有一个空闲监视器,如果用户空闲 5 分钟就会触发该监视器。它将打开一个确认对话框,该对话框将等待 2 分钟;之后它将重定向到登录页面。

需求:我想显示一个倒计时器,其中显示用户将被重定向到登录页面之前的剩余时间。

baseTemplate.xhtml:

<h:form>

    <p:idleMonitor timeout="#{idleMonitorView.timeoutVal}"
        onidle="startTimer()" />

    <p:confirmDialog id="confirmDialog"
        message="You have been idle, Please click ok to remain logged in"
        header="Are you there?" severity="alert" widgetVar="idleDialog">                 
        <p:commandButton id="confirm" value="Ok" oncomplete="extendSession()" />

    </p:confirmDialog>

    <p:remoteCommand name="terminateIdleSession" actionListener="#{idleMonitorView.onIdle}" out="count" />

    <script type="text/javascript">
        var extend_session = 0;
        function startTimer() {

            extend_session = 0;
            setTimeout("timeout()", 120000);
            PF('idleDialog').show();
        }

        function timeout() {
            if (extend_session == 0) {
                terminateIdleSession();
            }
        }

        function extendSession() {
            extend_session = 1;
            PF('idleDialog').hide();
        }
    </script>
</h:form>

问题:我不知道如何实现这个要求。

javascript primefaces dialog countdowntimer
2个回答
2
投票

您应该创建一个 JavaScript 间隔,每秒更新一次计时器(或您需要的任何其他间隔)。您可以使用一些 jQuery 来更新计时器。我建议在对话框消息中添加一个跨度,您可以将其用作计时器:

$("#myForm\\:confirmDialog .ui-confirm-dialog-message").append("<span id=logoffTimeout/>");

您应该将

myForm
替换为您在此处表单上使用的 ID。

显示对话框时,计算注销计时器到期的时间并将其存储在例如

window.logoffTime
中。现在您可以使用以下函数来更新计时器:

function updateTimer(){
  var seconds = Math.ceil((window.logoffTime - new Date().getTime()) / 1000);
  $("#logoffTimeout").html(seconds);
}

在您的按钮和远程命令上,我建议使用

process="@this"
。另请参阅:了解 PrimeFaces 进程/更新和 JSF f:ajax 执行/渲染属性

您应该知道的是,当您在 JavaScript 中启动超时时,会返回一个 ID。您可以使用该 ID 来清除超时。

我最终得到了这个 XHTML:

<p:confirmDialog id="confirmDialog"
                 message="Please click Ok before the timer runs out: "
                 header="Are you there?"
                 severity="alert"
                 closable="false"
                 widgetVar="idleDialog">
  <p:commandButton id="confirm"
                   value="Ok"
                   process="@this"
                   onclick="clearTimeout(window.logoffTimeoutId); PF('idleDialog').hide();"/>
</p:confirmDialog>

<p:remoteCommand name="terminateIdleSession"
                 actionListener="#{idleMonitorView.onIdle}"
                 process="@this"
                 out="count"/>

<p:idleMonitor timeout="#{5 * 60 * 1000}"
               onidle="startTimer()"/>

还有这个 JavaScript:

function startTimer() {
  clearTimeout(window.logoffUpdaterId);
  PF('idleDialog').show();
  // Set timeout to 2 minutes
  var timeout = 2 * 60 * 1000;
  // Calculate when the time runs out
  window.logoffTime = new Date().getTime() + timeout;
  // Start timer which calls remote command
  window.logoffTimeoutId = setTimeout(terminateIdleSession, timeout);
  // Update timer every second
  window.logoffUpdaterId = setInterval(updateTimer, 1000);
  // Update timer now
  updateTimer();
}

// Update the timer
function updateTimer() {
  var seconds = Math.ceil((window.logoffTime - new Date().getTime()) / 1000);
  $("#logoffTimeout").html(seconds);
}

// Create span to contain the timer
$(function(){
  $("#myForm\\:confirmDialog .ui-confirm-dialog-message").append("<span id=logoffTimeout/>");
});

我注意到您正在使用嵌入在 XHTML 中的 JavaScript。在这种情况下,添加

CDATA
以防止遇到 XML 错误:

<script type="text/javascript">
//<![CDATA[
...
//]]>
</script>

我建议从文件/资源加载脚本,这将为您带来缓存的好处。


0
投票

@Jasper de Vries 在 2017-04-29T18:13 的回答非常棒、优雅并且效果很好,我想补充一点,从 PF 版本 8 开始,“p:idleMonitor”组件具有“multiWindowSupport”参数,当配置为 true,最后访问的状态将在同一 servlet 上下文的所有浏览器窗口之间共享。

<p:idleMonitor timeout="#{5 * 60 * 1000}"
               onidle="startTimer()"
               multiWindowSupport="true"
/>

快乐编码;

© www.soinside.com 2019 - 2024. All rights reserved.