Saturday, October 20, 2007

FckEditor inside UpdatePanel broken

FckEditor (or Fck) is a lightweight, JavaScript based WYSIWYG html editor for web applications.  I find it one of the best html editors out there along with FreeTextBox (or FTB), a popular ASP.NET-centric html editor.  The best thing about both of the editors is that they are free.  The advantage of Fck it that is works with a couple of different web platforms including Java, PHP, and .NET.  However, one thing I have found lacking is the FckEditor's documentation

HTML Editor solutions usually rely on an iframe or div to be the actual html editor so they require a second hidden input field to be the input field that will post the value of the editor back to the server.  This is normally not a problem because they usually update the input field before the form is posted.  However the Microsoft AJAX UpdatePanel does not do normal form posts, so html editors like Fck and FTB don't get a chance to update their linked field.  I have yet to see an official fix from the developers of both these solutions.  Many people have asked "which editors work with UpdatePanel?", including the html editors that are not free including Telerik's RadEditor and Infragistics' NetAdvantage WebHtmlEditor.

I found two different solutions for fixing the FckEditor UpdatePanel updating problem.  The first solution handles the onclick event that triggers the async postback and then use a client-side JavaScript function to update the hidden linked input field.  The second solution I found was better because it attached to the OnSubmit event which works with both synchronous and asynchronous postback calls.  The second solution also updated all of the editors on the page instead of a specific one - the reason why I was looking for another solution in the first place.

Here is the C# code for the second solution (for the Page_Load event):

this.Page.ClientScript.RegisterOnSubmitStatement(
    this.GetType(),
    "AjaxHack",
    "for ( var i = 0; i < parent.frames.length; ++i ) if ( parent.frames[i].FCK ) parent.frames[i].FCK.UpdateLinkedField();"
    );