Monday, November 9, 2009

CKEditor integration with XPages (32k limited)

I've found a way around the 32k-limit. Read more here.

I've been asked several times to make an XPages integration with XPages. I finally buckled under the pressure last friday.

Initially I planned on making a full integration (no limits, bound to a NotesRichtextItem). Unfortunately, this is impossible using regular XPages components. I've tried a lot of hacks (rendererType, converting the field in different events, and a lot of other stuff I know nothing about), but so far I've been unable to make the integration work with the native XPages Rich Text editor control.

The last person that requested the integration was "fine" with a 32k limit on the demo, so I've extended the CKEditor Integration demo with a demo of XPages integration (bound to a regular text field).

Read the blog entry on CKEditor integration for prerequisites (CKEditor installed in a certain directory on the server).

>> Demoapp of CKEditor integration with Domino form and XPages


nesie said...

Very nice! I gave it try to work around the 32K limit and I think I stumbled onto something that seems to work. I just assumend your were right when you said the limitation is in the way XPages handles a textarea, so I decided to try and use a temporary RichText field that I create in the submit button, so it is not bound to the xpage and does not have the limitation. I then call a good old lotusscript agent in the postsave event that recreates the proper RichText field with the value of the temporary RichText field.

Here is the code I used:

- I have a Multi Line Edit control (inputTextarea1) bound to the richtext Body field of my form

- I have a submit button with this server side javascript:
var bodyHTML = getComponent('inputTextarea1').getValue();
var RTF:NotesRichTextItem = rtfDocument1.getDocument().createRichTextItem("BodyTemp");

- In the postSaveDocument event of my datasource I have the following script:
sessionScope.rtfid = rtfDocument1.getNoteID(); //documentId used by datasource
ckagent = database.getAgent("saveCKEditorData");
if (ckagent.runOnServer(sessionScope.rtfid)==0) {
var url = facesContext.getExternalContext().getRequest().getRequestURI();
url += "?documentId=" + sessionScope.rtfid + "&action=editDocument"
context.redirectToPage(url); //redirect needed (sometimes?) to open document with proper content...

- In the initialize event of the saveCKEditorData agent I have this lotusscript:

Dim session As New NotesSession
Dim db As NotesDatabase
Dim agent As NotesAgent
Dim doc As NotesDocument
Dim body As Variant
Dim bodytemp As NotesRichTextItem
Dim RichStyle As NotesRichTextStyle
Dim HTMLCode As Variant
Dim noteid As String

On Error GoTo errHandler

Set db = session.CurrentDatabase
Set agent = session.CurrentAgent
noteid = agent.ParameterDocID

Set doc = db.Getdocumentbyid(noteid)

If Not doc Is Nothing Then

Set RichStyle = session.CreateRichTextStyle

Set body = doc.Getfirstitem("Body")
If Not body Is Nothing then
Call body.remove()
End If
Set bodytemp = doc.Getfirstitem("BodyTemp")
HTMLCode= bodytemp.GetUnFormattedText()

Call bodytemp.Remove()
Set body = doc.CreateRichTextItem( "Body" )
Call body.AppendStyle( RichStyle )
Call body.AppendText(HTMLCode)

Call doc.Save(true, true, true)

End If

Exit Sub


Print "Error: " & Error$ & " (" + CStr(Err) + ") on line " & CStr(Erl)
resume endOfCode

Best regards,
Rene Paul