This is a migrated thread and some comments may be shown as answers.

Eat first keystroke on ajax post from client

5 Answers 64 Views
Editor
This is a migrated thread and some comments may be shown as answers.
John
Top achievements
Rank 1
John asked on 24 Feb 2011, 05:30 PM

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;
            }
        }

5 Answers, 1 is accepted

Sort by
0
Rumen
Telerik team
answered on 01 Mar 2011, 12:48 PM
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!
0
John
Top achievements
Rank 1
answered on 04 Mar 2011, 10:18 PM
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)
        {
 
        }
    }
}
0
Rumen
Telerik team
answered on 09 Mar 2011, 06:09 PM
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!
0
John
Top achievements
Rank 1
answered on 09 Mar 2011, 07:29 PM
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.


0
Rumen
Telerik team
answered on 11 Mar 2011, 04:45 PM
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!
Tags
Editor
Asked by
John
Top achievements
Rank 1
Answers by
Rumen
Telerik team
John
Top achievements
Rank 1
Share this question
or