Making Rich TextBoxes work in web enabled InfoPath forms

Technorati Tags: InfoPath 2007,rich text box,web enabled forms,InfoPath SharePoint,InfoPath WCF

Introduction

The rich-text boxes provide InfoPath forms with functionality that sometimes is crucial to the end users. However, there is not much information on the web with the tips on implementation. In this post I will skip reference to the RTB performance, which is known to be not that good. This blog will provide you with key steps to implement solution that delivers:

  1. Web-enabled InfoPath form with RTB hosted in SharePoint
  2. Support for the WCF service that ia bi-directionally connected to the database
  3. Read and Write RTB fields

Solution

In this sample solution the InfoPath form displays a list of records from the database. The form is hosted in the SharePoint. The user is able to edit a record (EDIT button)and create a new one (CREATE button). Each record has 2 fields that must provide Rich Text box functionality.

clip_image001

WCF design

The web service will return and accept a STRING field, not XmlNode. That is a key difference to the solution you can find at http://support.microsoft.com/kb/826996

NOTE: make sure that you have a TEXT field on the receiving end in the database. XHTML generated by RTB can be quite large.

Implementation

Step 1

Create fields for each the RTB in the main data-source. Only RTB in main XML tree will be able to handle both read and write functionality. You will end up with 2 fields per RTB.

clip_image002

Step 2

Bind plain fields fldNotes and fldDescription to the corresponding columns provided by the WCF service. One of the ways to accomplish that is to define Rule on the button. Here is how it was done for the editing functionality.

clip_image003

This logic insures that fldNotes has the Notes value of the edited record.

Step 3

Add code-behind to the same Edit button to parse text into XHTML. Code will be responsible for doing all the hard work on validation and parsing text into Xml.

   public void btnEdit_Clicked(object sender, ClickedEventArgs e)

        {

            XPathNavigator root = MainDataSource.CreateNavigator();

            PopulateRTB(root,

                "/my:myFields/my:SubmitData/my:fldNotes",

                "/my:myFields/my:SubmitData/my:richNotes");

           

            PopulateRTB(root,

                "/my:myFields/my:SubmitData/my:fldDescription",

                "/my:myFields/my:SubmitData/my:richDescription");

        }

        private void PopulateRTB(XPathNavigator root, string fldPath, string richPath)

        {

            XPathNavigator rich =

                root.SelectSingleNode(richPath, NamespaceManager);

            XPathNavigator fld =

                root.SelectSingleNode(fldPath, NamespaceManager);

            try

            {

                rich.InnerXml = GetXHTML(fld.Value).OuterXml;

            }

            catch

            {

                rich.SetValue(string.Empty);

            }

        }

        private XmlNode GetXHTML(string text)

        {

            XmlDocument doc = new XmlDocument();

            try

            {

   doc.LoadXml(text);

                return doc.DocumentElement;

            }

            catch (XmlException)

            {

                XmlNode node = doc.CreateNode(

                    XmlNodeType.Element,

                    "DIV",

  "http://www.w3.org/1999/xhtml");

                if (!string.IsNullOrEmpty(text))

                {

                    node.InnerText = text;

                }

                return node;

            }

        }

The methods account for having plain text returned by WCF, that is not Xml-structured.

Step 4

Add code-behind to the Submit button. This code insures writing Xml-structured text back to fldNotes and fldDescription.

   private void PopulateField(XPathNavigator root, string fldPath, string richPath)

        {

            XPathNavigator rich =

                root.SelectSingleNode(richPath, NamespaceManager);

            XPathNavigator fld =

                root.SelectSingleNode(fldPath, NamespaceManager);

            fld.SetValue(rich.InnerXml);

     }

        public void FormEvents_Submit(object sender, SubmitEventArgs e)

        {

            XPathNavigator root = MainDataSource.CreateNavigator();

            PopulateField(root,

                "/my:myFields/my:SubmitData/my:fldNotes",

          "/my:myFields/my:SubmitData/my:richNotes");

            PopulateField(root,

                "/my:myFields/my:SubmitData/my:fldDescription",

                "/my:myFields/my:SubmitData/my:richDescription");

        }

Step 5

In your Update and Create connections make sure that fldNotes and fldDescription are bound to corresponding WCF services.

clip_image004[5]

Run the form and enjoy rich text boxes in action!

Conclusion

Now, after you made RTB work and enjoyed all the richness it offers, remember! RTB impacts performance. Run your stress/scalability/performance tests before go for production.