Eat first keystroke on ajax post from client

6 posts, 0 answers
  1. John
    John avatar
    33 posts
    Member since:
    Jun 2010

    Posted 24 Feb 2011 Link to this post

    When checking to see if the document has been modified, I’m having a problem where the first key stroke is eaten.  On the first key stroke that makes the document dirty I send an ajax message to the server indicating the document is dirty and it is that first key stroke that gets eaten.  Other key strokes are ignored and no messages are sent.  Of course I’m assuming it’s the interaction with the ajax message that causes the key stroke to be eaten. 

    Was wondering if anyone had a suggestions what to look into. 

    Thanks.
    ___
    Client Side

    function OnKeyDown_Editor(e) {
                //debugger;
                if("<%=AllowTextEntry%>".toLowerCase()=="true".toLowerCase()){
                    if(isPrintable_orDelete(e.keyCode)){
                        SetDocumentDirtyState(true);
                    }
                }
                e.returnValue = <%=AllowTextEntry%>;//set to true most times
        }
     
       function SetDocumentDirtyState(MakeItDirty){
            var IsDirty=GetCookie("<%=EditorDirtyCookieName%>");
            if(MakeItDirty==true){
                if(IsDirty!='true'){
                    /*
                     * write code to lock this document in database
                     */
                     var message="EditorIsDirty-true";
                     SendAjaxMessage(message);
                }
                SetCookie("<%=EditorDirtyCookieName%>",true,1);
            }
            else{
                deleteCookie("<%=EditorDirtyCookieName%>");
            }
        }
    ______Server Side:

           protected void Page_Load(object sender, EventArgs e)
            {
                if (!Page.IsPostBack)
                {
                /*
                 * Setup Ajax Management
                 */
                //Get reference to AjaxManager (from Master)
                var manager = RadAjaxManager.GetCurrent(this);
     
                //Create a new delegate to handle the AjaxRequest event
                manager.AjaxRequest += new RadAjaxControl.AjaxRequestDelegate(RadAjaxPanel1_AjaxRequest);
                manager.AjaxSettings.AddAjaxSetting(manager, this.RadEditor1);
     
     
            }
     
           protected void RadAjaxPanel1_AjaxRequest(object sender, AjaxRequestEventArgs e)
            {
                string Action = null;
                string MyArgument = null;
                try
                {
                    int Index=e.Argument.IndexOf("-");
                    if(Index>0)Index++;//include the "-"
                    Action = e.Argument.Substring(0, Index);
                    MyArgument = e.Argument.Substring(Index);
                }
                catch (Exception exc) {
                }
     
     
                switch (Action)
                {
                    case "EditorIsDirty-":
                        if(MyArgument=="true"){
                            /*eating character?*/
                        }
                        break;
                }
            }

  2. Rumen
    Admin
    Rumen avatar
    13980 posts

    Posted 01 Mar 2011 Link to this post

    Hello John,

    The provided information and code is not enough to reproduce the problem. Can you please isolate the issue in a simple fully working project and send it for examination on our side? Please, provide detailed steps how to replicate it too.

    Best regards,
    Rumen
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  3. John
    John avatar
    33 posts
    Member since:
    Jun 2010

    Posted 04 Mar 2011 Link to this post

    Procedure to see problem;
    * compile and run attatched
    * Type the first letter into the editor.  Notice that first character
      disappears.  What is causing the problem is the near last line of
      page load of deafault.aspx.cs ("manager.AjaxSettings.AddAjaxSetting(manager
      , this.RadEditor1);").   

      What I'm trying to do is in certain cases open a save "popup" radwindw,
      capture the users response as to whether to save or not.  Pass it back to
      the content page which will act on message recieved.

      If you comment out the line at the end of pageload (...AddAjaxSetting...)
      and try to run the program and enter a key,  it will not be eaten.  But
      the Save dialog will not communicate via ajax the save event to the content
      page.

    * To activate the save event click "ForceSaveDialogChallenge", set a   "debugger"(or break point)

       For Default.aspx
       - Break point can be set on line 46,OnKeyDown_Editor method, this
         method makes the document 'dirty'
       - Break point on line 120,Show_ConfirmEditorSave, which launches save
         dialog
       - break point on line 134 of OnClientClose_SaveEditor which is called on
         successful ajax call from save dialog, it then sends a message to
         content page.

    Default.aspx
    <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
        CodeBehind="Default.aspx.cs" Inherits="KeyEat._Default" %>
     
    <%@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>
     
    <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    </asp:Content>
    <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <br />
        <h2>
             <asp:Button ID="Button1" runat="server" onclick="Button1_Click"
                Text="Force Save Dialog Challenge" />
        </h2>
    <br />
        <telerik:RadEditor ID="RadEditor1" Runat="server"
            OnClientLoad="OnClientLoad_RadEditor"
        >
            <Tools>
                <telerik:EditorToolGroup>
                    <telerik:EditorTool Name="Save Editor" />
                </telerik:EditorToolGroup>
            </Tools>
    </telerik:RadEditor>
     
     
    <telerik:RadCodeBlock ID="cb1" runat="server">
    <script type="text/javascript">
        window.onbeforeunload = ConfirmWindowClose;
     
        /*
         * on document close force a last chance save (not required for dem of problem
         */
        function ConfirmWindowClose(e) {
            if (GetCookie("<%=NotAWindowCloseEventName%>") != "<%=BoolTrue%>") {
                if (GetCookie("<%=EditorDirtyCookieName%>") == "<%=BoolTrue%>") {
                    var radManager;
                    //Get reference to RadAjaxManager on page
                    if (radManager === undefined)
                        radManager = $find('<%= RadAjaxManager.GetCurrent(this).ClientID %>');
     
                    //Fire ajax request (optionally pass an event arg value)
                    var PassedArgument = "PageCloseOcurred-";
                    radManager.ajaxRequest(PassedArgument);
                    setTimeout('Show_ConfirmEditorSave();', 1000);
                    return "Editor is not saved!";
                }
            }
        }
     
        /*
         * Keydown handler
         */
        function OnKeyDown_Editor(e) {
            //debugger;
            if(isPrintable_orDelete(e.keyCode)){
                SetDocumentDirtyState(true);
            }
            e.returnValue = true;
        }
        function isPrintable_orDelete(keyCode) {
            var MyBackspace = 8;
            var MyDelete = 46;
            if ((keyCode > 31 && keyCode < 126) || (keyCode = MyDelete) || (keyCode = MyDelete)) {
                return true;
            }
            return false;
        }
        function SendAjaxMessage(Message) {
            var radManager;
     
            if (radManager === undefined) {
                radManager = $find('<%= RadAjaxManager.GetCurrent(this).ClientID %>');
            }
     
            //Fire ajax request (optionally pass an event arg value)
            var PassedArgument = Message
            radManager.ajaxRequest(PassedArgument);
        }
     
        /*
        * Sets vars and makes call to codebehind indicating the editor is dirty
        */
        function SetDocumentDirtyState(MakeItDirty) {
            var IsDirty = GetCookie("<%=EditorDirtyCookieName%>");
            if (MakeItDirty == true) {
                if (IsDirty != 'true') {
                    /*
                    * write code to lock this document in database
                    */
                    //alert('is dirty');
                    var message = "EditorIsDirty-true";
                    SendAjaxMessage(message);
     
                }
                SetCookie("<%=EditorDirtyCookieName%>", true, 1);
            }
            else {
                deleteCookie("<%=EditorDirtyCookieName%>");
            }
        }
     
        /*
         * Attatch the event handler for keystrokes in the editor
         */
        function OnClientLoad_RadEditor(editor, args) {
            editor.attachEventHandler("onkeydown", OnKeyDown_Editor);
        }
        function GetCookie(CookieName) {
            var CookieVal = null;
            if (document.cookie)       //only if exists
            {
                var arr = document.cookie.split((escape(CookieName) + '='));
                if (arr.length >= 2) {
                    var arr2 = arr[1].split(';');
                    CookieVal = unescape(arr2[0]); //unescape() : Decodes the String
                }
            }
            return CookieVal;
        }
     
        function SetCookie(cookieName, cookieValue, nDays) {
            var today = new Date();
            var expire = new Date();
            if (nDays == null || nDays == 0) nDays = 1;
            expire.setTime(today.getTime() + 3600000 * 24 * nDays);
            document.cookie = cookieName + "=" + escape(cookieValue)
                + ";expires=" + expire.toGMTString();
        }
     
       /*
        * Launches the save editor radwindow
        */
        function Show_ConfirmEditorSave() {
            var oManager = GetRadWindowManager();
            var oWnd = radopen(null, "ConfirmSaveEditor");
            oWnd.add_close(OnClientClose_SaveEditor);
            SetCookie("<%=NotAWindowCloseEventName%>", "<%=BoolTrue%>", 1);
        }
     
        /*
        * When the popup confirm save window comes up and the user clicks a button the argument
        * is returned here.  It is evaluated and if true an ajax message is sent to codebehind
        * for processing, doing those things that a save requires
        */
        function OnClientClose_SaveEditor(oWnd, args) {
            //get the transferred arguments
            //debugger;
            var arg = args.get_argument();
            if (arg) {
                //Fire ajax request (optionally pass an event arg value)
                var PassedArgument = "SaveEditor-" + arg.SaveIt
                SendAjaxMessage(PassedArgument);
            }
        }
        /*
         * Save button on editor, not really necesary for demo of problem
         */
        Telerik.Web.UI.Editor.CommandList["Save Editor"] = function (commandName, editor, args) {
            //SetCookie("NonSelectEventOccurred",true,1);
            //debugger;
            var radManager;
            //Get reference to RadAjaxManager on page
            if (radManager === undefined)
                radManager = $find('<%= RadAjaxManager.GetCurrent(this).ClientID %>');
     
            //Fire ajax request (optionally pass an event arg value)
            var PassedArgument = "SaveEditor-true";
            radManager.ajaxRequest(PassedArgument);
     
     
        };
    </script>
    </telerik:RadCodeBlock>
     
    </asp:Content>

    Default.aspx.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Telerik.Web.UI;
     
     
    namespace KeyEat
    {
        public partial class _Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                var manager = RadAjaxManager.GetCurrent(this);
     
                //Create a new delegate to handle the AjaxRequest event
                manager.AjaxRequest += new RadAjaxControl.AjaxRequestDelegate(RadAjaxPanel1_AjaxRequest);
     
                //The following needs to be enable so the save splash dialog works and returns editor to proper page
                /* !
                 * !The following line is causing the first keystroke to be eaten even though line is required to
                 * !   get the save dialog to send ajax message to this client to save document in editor, not
                 * !   sure how to fix this as of yet.
                 */
                 
                manager.AjaxSettings.AddAjaxSetting(manager, this.RadEditor1);
     
            }
     
            protected void RadAjaxPanel1_AjaxRequest(object sender, AjaxRequestEventArgs e)
            {
                string Action = null;
                string MyArgument = null;
                try
                {
                    int Index = e.Argument.IndexOf("-");
                    if (Index > 0) Index++;//include the "-"
                    Action = e.Argument.Substring(0, Index);
                    MyArgument = e.Argument.Substring(Index);
                }
                catch (Exception exc)
                {
                }
     
                SiteMaster sm = (SiteMaster)Master;
     
     
                /*
                 * Right now this is for the case of confirm saving of editor, later this
                 * switch may be expanded for other AjaxRequest calls
                 */
                switch (Action)
                {
                    case "SaveEditor-":
                        break;
                    case "EditorIsDirty-":
                        if (MyArgument == "true")
                        {
                            //todo:add code here to notify the database that the document is dirty.
                        }
                        break;
                    case "PageCloseOcurred-":
                        /*
                         * This fires when ever application page is refreshed or navigated away from
                         * or closed and it should fire only if editor is dirty.  Logic is
                         * in place to prevent firing if manual selection has changed.
                         */
     
                        break;
                }
            }
            private void SaveEditorDialogPrompt()
            {
                string MyStript =
                        "<script type=\"text/javascript\">\n" +
                        "  setTimeout('Show_ConfirmEditorSave();',1000);" +
                        "</script>\n";
                ClientScript.RegisterClientScriptBlock(this.GetType(), Guid.NewGuid().ToString(), MyStript);
            }
     
            public string NotAWindowCloseEventName
            {
                get
                {
                    KeyEat.Properties.Settings MySettings = new Properties.Settings();
                    return MySettings.Cookie_NotAWindowCloseEvent;
                }
            }
            public string BoolFalse
            {
                get
                {
                    return bool.FalseString.ToLower();
                }
            }
            public string BoolTrue
            {
                get
                {
                    return bool.TrueString.ToLower();
                }
            }
            public string EditorDirtyCookieName
            {
                get
                {
                    KeyEat.Properties.Settings MySettings = new Properties.Settings();
                    return MySettings.Cookie_EditorTextChanged;
                }
            }
     
            protected void Button1_Click(object sender, EventArgs e)
            {
                SaveEditorDialogPrompt();
            }
     
        }
    }


    ConfirmSaveEditor.aspx
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ConfirmSaveEditor.aspx.cs" Inherits="NVSS_Manual.ConfirmSaveEditor" %>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     
    <head runat="server">
        <title>Confirm Save Editor</title>
    </head>
    <body>
        <form id="form1" runat="server">
    <script type="text/javascript">
        function GetRadWindow() {
            var oWindow = null;
            if (window.radWindow) oWindow = window.radWindow;
            else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow;
            return oWindow;
        }
        function returnToParent(SaveIt)
        {
            //create the argument that will be returned to the parent page
            var oArg = new Object();
            oArg.SaveIt = SaveIt;
            var oWnd = GetRadWindow();
                 
            //Close the RadWindow and send the argument to the parent page
            oWnd.close(oArg);
        }
    </script>
        <div style="font-family: Arial; font-size: large; margin-left:auto; margin-right:auto; text-align:center">
            Save Editor Content?</div>
            <table style="margin-left:auto; margin-right:auto; text-align:center">
                <tr>
                    <td>
                        <button title="Yes_Confirm" id="Yes_Confirm" onclick="returnToParent(true); return false;">Yes</button>
                    </td>
                    <td>
                        <button title="No_Confirm" id="No_Confirm" onclick="returnToParent(false); return false;">No</button>
                    </td>
                </tr>
            </table>
        </form>
      
    </body>
    </html>
    ConfirmSaveEditor.aspx.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
     
    namespace NVSS_Manual
    {
        public partial class ConfirmSaveEditor : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
     
            }
        }
    }


    SiteMaster.aspx
    <%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="KeyEat.SiteMaster" %>
     
    <%@ Register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head runat="server">
        <title></title>
        <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
        <asp:ContentPlaceHolder ID="HeadContent" runat="server">
        </asp:ContentPlaceHolder>
    </head>
    <body>
        <form runat="server">
        <telerik:RadScriptManager ID="RadScriptManager1" Runat="server">
        </telerik:RadScriptManager>
        <telerik:RadWindowManager ID="RadWindowManager1" runat="server">
            <Windows>
                <telerik:RadWindow ID="ConfirmSaveEditor" runat="server" Modal="True"
                    NavigateUrl="ConfirmSaveEditor.aspx" style="display:none;">
                </telerik:RadWindow>
            </Windows>
        </telerik:RadWindowManager>
        <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
        </telerik:RadAjaxManager>
        <div class="page">
            <div class="header">
                <div class="title">
                    <h1>
                        My ASP.NET Application
                    </h1>
                </div>
                <div class="loginDisplay">
                    <asp:LoginView ID="HeadLoginView" runat="server" EnableViewState="false">
                        <AnonymousTemplate>
                            [ <a href="~/Account/Login.aspx" ID="HeadLoginStatus" runat="server">Log In</a> ]
                        </AnonymousTemplate>
                        <LoggedInTemplate>
                            Welcome <span class="bold"><asp:LoginName ID="HeadLoginName" runat="server" /></span>!
                            [ <asp:LoginStatus ID="HeadLoginStatus" runat="server" LogoutAction="Redirect" LogoutText="Log Out" LogoutPageUrl="~/"/> ]
                        </LoggedInTemplate>
                    </asp:LoginView>
                </div>
                <div class="clear hideSkiplink">
                    <asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal">
                        <Items>
                            <asp:MenuItem NavigateUrl="~/Default.aspx" Text="Home"/>
                            <asp:MenuItem NavigateUrl="~/About.aspx" Text="About"/>
                        </Items>
                    </asp:Menu>
                </div>
            </div>
            <div class="main">
                <asp:ContentPlaceHolder ID="MainContent" runat="server"/>
            </div>
            <div class="clear">
            </div>
        </div>
        <div class="footer">
             
        </div>
        </form>
    </body>
    </html>

    Site.Master.aspx.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
     
    namespace KeyEat
    {
        public partial class SiteMaster : System.Web.UI.MasterPage
        {
            protected void Page_Load(object sender, EventArgs e)
            {
     
            }
        }
    }
  4. Rumen
    Admin
    Rumen avatar
    13980 posts

    Posted 09 Mar 2011 Link to this post

    Hello John,

    I created a web application project based on the provided information, however I got JavaScript error when I tested the project. The problem is due to that I commented the following lines:

    KeyEat.Properties.Settings MySettings = new Properties.Settings();
    
    
    In the 
    NotAWindowCloseEventName
    and
    
    EditorDirtyCookieName 
    
    properties declarations.

    Can you please modify the attached project to my reply so that it demonstrates the problem and send it for examination after that?

    All the best,
    Rumen
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  5. John
    John avatar
    33 posts
    Member since:
    Jun 2010

    Posted 09 Mar 2011 Link to this post

    Thanks so much for your reply.

    How may I send the zipped solution, since your "attach your files" component will not allow that file type?

    I can provide a  ftp url (read only site) to so you can get it if that works for you?

    Thanks.


  6. Rumen
    Admin
    Rumen avatar
    13980 posts

    Posted 11 Mar 2011 Link to this post

    Hi John,

    You can use the support ticketing system under your account to attach zipped files to the tickets, which we can download and review.

    Best regards,
    Rumen
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
Back to Top