How To: Timeout (Client Side) using postMessage (HTML5) with Countdown alert

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1

    How To: Timeout (Client Side) using postMessage (HTML5) with Countdown alert

    It's my first Englis How To... I hope can help others. Sorry my English isn't very good. Corrections are welcome!

    Finally I can do TimeOut at client side... you need a browser with postMessage (HTML5) compatibility.

    My first implementation was create an mouse and keyboard detection. But I'm using tab panel, and any tab panel is an iFrame then my script only works in the master page, but not in any tab. Then I'm trying to catch mouse and keyboard events in any iFrame and send this to master and run the script in the master page, but this actions was blocked by browsers to prevent hacking actions.

    Surfing into the web I found in HTML the postMessage that is used to send message between windows and iFrames.
    Here an example how it works: http://robertnyman.com/2010/03/18/po...s-and-iframes/

    Then now I can catch the events in any iFrame but the action is run directly in the master page.

    NOTE: I'm working with MVC

    1: Create a TimeOut.js into Scripts folder file with this content:

    // Session Timeout client side. Master and Detail detection.
    /**
    * Detecting in Master and Detail, Mouse and Keyboard events.
    * Using postMessage (HTML5)
    * @autor   Camilo Martinez [Equiman], http://gplus.to/equiman
    * @created 2012-04-11
    * @updated 2012-04-22
    * @licence CC BY-SA http://creativecommons.org/licenses/by-sa/3.0/
    */
    
    // Add this into Master Page (TabPanelContain):
    // <DocumentReady Handler="masterTimeOut();" />
    var masterTimeOut = function () {
    
        //Convert minutes value indicated in TimeOut del Web.Config to seconds
        var min = 0;
        var sec = 0;
        var timer = null;
        var vis = false;
    
        doTimer = function () {
            // At least 1 min, show the countdown window
            if ((min - sec) < 60) {
    
                updateTime();
    
                if (frmTimeOut.hidden) {
                    vis = true;
                    frmTimeOut.setVisible(true);
                }
            }
            else {
                if (!frmTimeOut.hidden) {
                    vis = false;
                    frmTimeOut.setVisible(false);
                }
            }
    
            // Check the countdown counter
            if ((min - sec) > 0) {
                sec++;
                // Repeat the process each minute
                timer = setTimeout('doTimer()', 1000);
            }
            else {
                // When countdown is finish, redirect to Login page
                top.location.replace(GetNewPath('/Home/Login/'));
            }
        };
    
        stopCount = function () {
            if (vis === true) {
                //2 seconds Idle (no detect events, because showing alert window is detected as mousemove)
                if ((min - sec) < 58) {
                    vis = false;
                }
            }
            else {
                // Convert minutes to second, minus 10 to be sure Client TimeOut occurs first than Server Timeout
                min = (document.getElementById('txtMinTimeOut').value * 60) - 10;
                sec = 0;
                clearTimeout(timer);
                doTimer();
            }
        };
    
        updateTime = function () {
            var message = 'Inactivity was detected. Your session will expire in';
            var time = (min - sec);
            var unity = 'seconds.';
    
            Ext.getCmp('lblText').setText(message + ' ' + time + ' ' + unity);
        };
    
        // Start counter on Load
        document.onload = function () {
            stopCount();
            return false;
        };
        // Star counter when mouse move
        document.onmousemove = function () {
            stopCount();
            return false;
        };
        // Star counter when key is pressed
        document.onkeypress = function () {
            stopCount();
            return false;
        };
    
        // Read and event when is send from an iFrame
        function displayMessage(e) {
            if ((e.origin.split(":", 2)[0] + ":" + e.origin.split(":", 2)[1]) === (GetNewPath("/").split(":", 2)[0] + ":" + GetNewPath("/").split(":", 2)[1])) {
                // If the iFrame send any of this events start counter
                switch (e.data) {
                    case "onload":
                    case "onmousemove":
                    case "onkeypress":
                        stopCount();
                }
            }
        };
    
        if (window.addEventListener) {
            // For standards-compliant web browsers
            window.addEventListener("message", displayMessage, false);
        }
        else {
            window.attachEvent("onmessage", displayMessage);
        };
    };
    
    
    // Add this into any iFrame Page:
    // <DocumentReady Handler="detailTimeOut();" />
    var detailTimeOut = function () {
        // Start counter on Load
        document.onload = function () {
            top.postMessage("onload", GetNewPath("/"));
            return false;
        };
        // Star counter when mouse move
        document.onmousemove = function () {
            top.postMessage("onmousemove", GetNewPath("/"));
            return false;
        };
        // Star counter when key is pressed
        document.onkeypress = function () {
            top.postMessage("onkeypress", GetNewPath("/"));
            return false;
        };
    };
    
    
    // Get the Path when use VirtualPath in .Net or IIS
    var GetNewPath = function (relative_path) {
        var url = window.location.href;
    
        if (url.substring(url.length - 1, url.length) == '/') {
            url = url.substring(0, url.length - 1);
        }
    
        var url_parts = url.split('/');
    
        if (relative_path.substring(0, 1) != '/') {
            url_parts[url_parts.length - 2] = relative_path;
            url_parts[url_parts.length - 1] = '';
        }
        else {
            url_parts[url_parts.length - 2] = relative_path.substring(1);
            url_parts[url_parts.length - 1] = '';
        }
    
        var new_page_absolute_path = url_parts.join('/');
    
        if (new_page_absolute_path.substring(new_page_absolute_path.length - 1, new_page_absolute_path.length) == '/') {
            new_page_absolute_path = new_page_absolute_path.substring(0, new_page_absolute_path.length - 1);
        }
    
        return new_page_absolute_path;
    };
    2: Add the timeout to Web.Config (in minutes). Into <system.web> add:
    <sessionState timeout="5"></sessionState>
    3: Read into master page the TimeOutValue.

    Add Namespace System.Web
    <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <%@ Import Namespace="System.Web" %>
    Into <head> tag read the TimeOut time and send to Hidden TextField:
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack && !X.IsAjaxRequest)
            {
                txtMinTimeOut.Value = Session.Timeout;
            }
        }
    </script>
    Into <body><form> tags tead the TimeOut.js, when Document Ready load the masterTimeout() and create the Hidden Text Field:
    <asp:ScriptManager ID="smmaster" EnableScriptLocalization="true" runat="server">
        <Scripts>
             <asp:ScriptReference Path="~/Scripts/TimeOut.js" />
        </Scripts>
    </asp:ScriptManager>
    <ext:ResourceManager ID="ResourceManagerMaster2" runat="server">
        <Listeners>
            <DocumentReady Handler="masterTimeOut();" />
        </Listeners>
    </ext:ResourceManager>
    
    <ext:Hidden ID="txtMinTimeOut" runat="server" />
    Create a Window to show the countdown alert, before </form> tag:
    <ext:Window 
        ID="frmTimeOut" 
        runat="server" 
        Width="235" 
        Height="50" 
        Modal="false"
        Resizable="False"
        Hidden="true"
        Closable="false"
        Layout="FormLayout"
        Draggable="false"
        Padding="12">
        <Items>
            <ext:Label ID="lblText" runat="server" HideLabel="true" Text="" AutoWidth="true" />
        </Items>
    </ext:Window>
    4: In any iFrame (page loaded into Iframe or Tab Panel) add Into <body><form> tags tead the TimeOut.js, when Document Ready load the detailTimeout():

    <asp:ScriptManager ID="smDetail" EnableScriptLocalization="true" runat="server">
    <Scripts>
        <asp:ScriptReference Path="~/Scripts/TimeOut.js" />
    </Scripts>
    </asp:ScriptManager>
    <ext:ResourceManager ID="ResourceManager1" runat="server">
        <Listeners>
            <DocumentReady Handler="detailTimeOut();" />
        </Listeners>
    </ext:ResourceManager>
    And it's Done!!!
    Last edited by equiman; Nov 13, 2014 at 1:29 PM.

Similar Threads

  1. How to add HTML5 video tag in side form panel
    By arunsathyan in forum 1.x Help
    Replies: 2
    Last Post: Feb 15, 2022, 8:12 PM
  2. Replies: 4
    Last Post: Mar 19, 2010, 11:35 AM
  3. Replies: 0
    Last Post: Sep 17, 2009, 8:04 AM
  4. Ext.Msg.Alert from client script error
    By rthiney in forum 1.x Help
    Replies: 3
    Last Post: Jul 09, 2009, 3:51 PM
  5. Replies: 2
    Last Post: Jul 09, 2009, 2:35 PM

Tags for this Thread

Posting Permissions