How To: Spell Check an InfoPath form displayed via XmlFormView.

In my first post, I thought I would share how to use the SharePoint SpellCheck web service to spell check an InfoPath form displayed in an ASP.NET page using the XmlFormView control.

 I first turned to Kai Sheng’s blog which describes how to add spell check capability to a web form.  Unfortunately, with the Forms Service form, this technique did not work because the spell checked words would always revert back to their original form when attempting to submit the form.  I tried digging into the client-side JavaScript to see if I could understand what was going wrong.  I spent a long time on this effort, but was unsuccessful because I didn’t really know what I was looking for. 

 Finally, I stumbled across the InfoPath Forms Services 2007 Web Testing Toolkit:  http://www.codeplex.com/ipfswebtest  On this site is some excellent background information.  The key piece of information on this site that led to that aha moment for me was the event log.  I had noticed references to the event log in some of the SharePoint JavaScript code, but I ignored it because I somehow equated it to something like writing to the Windows Event Log.  Instead, the event log is really more like a SharePoint forms services transaction log that gets processed when the form is submitted.  Without an accurate event log, transactions cannot be properly processed. 

 So, after some digging, I ran across the RichTextBox.PersistPlainText function in the core.js file.  This was the key to getting form data to be persisted properly after the spell check function was run.

 NOTE:  All modifications suggested herein are to be made to a custom JavaScript file and NOT an existing SharePoint js file.  Also, please note I am a JavaScript novice.


Without further ado, here are the mods that need to occur:

  1.  Copy the %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033\SpellCheckEntirePage.js to a new file CustomSpellCheckEntirePage.js in the same directory. 

  2. Replace this text: 

  else if (null!=spelledChunks[index].Html && null!=spellableFields[spelledChunks[index].Index].id)

      {

               var strBaseElementID=spellableFields[spelledChunks[index].Index].id.replace(/\$/g, "_");

            var docEditor=RTE_GetEditorDocument(strBaseElementID);

               docEditor.body.innerHTML=spelledChunks[index].Html;

with this:

else if (null!=spelledChunks[index].Html && null!=spellableFields[spelledChunks[index].Index].id)

      {

  var strBaseElementID=spellableFields[spelledChunks[index].Index].id.replace(/\$/g, "_");

var docEditor=RTE_GetEditorDocument(strBaseElementID);

 var strHtml=spelledChunks[index].Html;

 docEditor.body.innerHTML=strHtml;

 var elemSave=document.getElementById(strBaseElementID);

 elemSave.value=strHtml;

 RichTextBox.PersistPlainText(elemSave);                                               

  1. Be sure that the web page is configured as outline here:  substituting the CustomSpellCheckEntirePage.js for SpellCheckEntirePage.js in the following control reference:  <SharePoint:ScriptLink language="javascript" name="SpellCheckEntirePage.js" runat="server" />  

If you ran the code at this point, you would be able to see the corrected words after submitting the form, but the form will be displaying the HTML markup.... So, we need to customize the RichTextBox.PersistPlainText. 

  1. Copy the RichTextBox.PersistPlainText function from %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\INC\Core.js to the beginning of the CustomSpellCheckEntirePage.js file.
  2. Rename the RichTextBox.PersistPlainText function in the CustomSpellCheckEntirePage.js file to RichTextBox_CustomPersistPlainText,
  3. Also change the call in CustomSpellCheckEntirePage from RichTextBox.PersistPlainText to RichTextBox_CustomPersistPlainText.
  4. Search for this section of  the RichTextBox_CustomPersistPlainText function:

else

{var arrValue                = new Array;

arrValue.push(strPlainText);

strPlainText = RichTextBox.QuickEncode(strPlainText);

var strValue = "

" + strPlainText + "
";

objControl.style.display            = "none";

objRichText.style.display          = "block";

arrValue.push(strValue);

8.  Replace the text in section 7 with the following:

else

{var strValue = "";

var strNoDivPlainText=strPlainText;

if (strPlainText.indexOf("

")!= -1)

{strNoDivPlainText=strPlainText.replace("

","");

strNoDivPlainText=strNoDivPlainText.replace("

","");

strValue=strNoDivPlainText;

}

else

{strValue = strNoDivPlainText;

}

objControl.style.display            = "none";

objRichText.style.display          = "block";

Now we are handling RichTextBoxes correctly.  What about regular text boxes?

9.  Create a function to persist regular text boxes, paste into the beginning of the CustomSpellCheckEntirePage.js file.  The function is defined as:

//Persist text box

TextBox_CustomPersistPlainText = function(objControl)

{var strValue = objControl.value;

var objViewDataNode = ViewDataNode.GetViewDataNodeFromHtml(objControl);

objControl.style.display      = "none";

TextBox.AddEventLogEntry(objControl, objViewDataNode);

TextBox.SetValueOfControl (objControl, strValue);

objViewDataNode[4] = false;

(objViewDataNode._boolDirty = true);

ViewDataNode.OnControlChange(objControl);

objViewDataNode._plainTextQueried = true;

ErrorVisualization.UpdateAllAsterisks;};

10.  Replace the following section:

if ("INPUT"==spellableFields[spelledChunks[index].Index].tagName)

{

if ("text"==spellableFields\[spelledChunks\[index\].Index\].type)

         {

          spellableFields[spelledChunks[index].Index].value=spelledChunks[index].Text;

}

with this one

if ("INPUT"==spellableFields[spelledChunks[index].Index].tagName)

{

if ("text"==spellableFields\[spelledChunks\[index\].Index\].type)

         {         

          var strValue = spelledChunks[index].Text;

                  spellableFields[spelledChunks[index].Index].value=strValue;

                  var strBaseElementID=spellableFields[spelledChunks[index].Index].id.replace(/\$/g, "_");

                  var elemSave=document.getElementById(strBaseElementID);

                  elemSave.value=strValue;

                 TextBox_CustomPersistPlainText(elemSave);  

}

 I hope that this is helpful to others.  I intend to post a follow-up on how to skip spell-checking for read-only fields.


This article is part of the GWB Archives. Original Author: Steve Cavanagh

New on Geeks with Blogs