I currently have a client who is using SharePoint in a rather unconventional way; although they want to use the publishing features of SharePoint, they wanted to provide their own front-end user interface for collecting information from the user, after which they will use the SharePoint object model to stuff those collected values into the underlying fields of the list item.
Because of this requirement, my clients have created an application page which pops up in a modal dialog window. That application page has a form which users can fill out. When they click the “save” button, the underlying code will create or update a publishing page in the Pages library. The client still wanted to use the Rich Image, Rich Link, and Rich HTML editor controls, but they needed these controls to not be directly bound to an underlying field (since the editor controls do not exist on a publishing page that is directly bound to underlying fields.)
This article will walk you through the process of getting these controls working on an application page.
All three of these controls are included in the Microsoft.SharePoint.Publishing assembly, so to get this working, you first need to add the following directive to the top of your application markup (.aspx) page:
<%@Register TagPrefix="CMS" Assembly="Microsoft.SharePoint.Publishing, Version=18.104.22.168, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.Publishing.WebControls"%>
To add a Rich Image control to your page, add the RichImageSelector control to your markup, like this:
<CMS:RichImageSelector ID="richImageSelector" runat="server" />
To add a Rich Link control to your page, add the RichLinkSelector control to your page, like this:
<CMS:RichLinkSelector ID="richLinkSelector" runat="server" />
And finally, to add a Rich HTML control your page, add the HtmlEditor control, like this:
<CMS:HtmlEditor ID="htmlEditor" runat="server" />
In your code behind, retrieving the values for the Image control and the Link control are fairly straight-forward.
Say you have a RichImageSelector control on your page, and it has an ID of richImageSelector. If you had a list item with a column of type ImageField called “Page Image”, you could easy update the list item’s column value like this:
li["Page Image"] = richImageSelector.Value;
You can do the same with a control of type RichLinkSelector that populates a LinkField called “Page Link”:
li["Page Link"] = richLinkSelector.Value;
Getting the HTML Editor wired up takes a little bit more work. Before I explain how it works, I want to give you a little background.
There are 3 classes that are all connected when you normally edit a SharePoint field in the browser:
- There’s a control that renders the actual user interface a user needs to edit the value of a field; this is the actual editing area that is connected to the ribbon. For the Rich HTML Editor, this control is the Microsoft.SharePoint.Publishing.WebControls.HtmlEditor control.
- There’s the underlying field which has no user interface of its own; it’s simply a definition of what kind of data gets stored in the database. (A DateTime field stores a date, a Number field stores an integer or a decimal number, an HTML field stores a string of HTML, etc.) The Rich HTML Editor stores data in an underlying site column that has a type of “HTML”, which is defined in the Microsoft.SharePoint.Publishing.Field.HtmlField class.
- There’s a hybrid control that is typically the control which gets added to a typical New/Edit/Display form for a list item, or a publishing page. This control basically takes the editor control (mentioned in the first bullet) and binds it to the underlying field (mentioned in the second bullet.) For the Rich HTML Editor, the Microsoft.Publishing.WebControls.RichHtmlField control contains a child control — the HtmlEditor control — and it’s bound to an underlying column of type HtmlField (the name of which gets passed in as a property of the control.)
Why is this important to know? Because the HtmlEditor control needs to have a RichHtmlField control associated with it. Without it, it won’t work. This can seem counter-intuitive, since that RichHtmlField doesn’t actually have any underlying field that it’s bound to. However, apparently that’s okay. The only requirement of the RichHtmlField seems to be that it requires its ControlMode to be set. I believe the reason you need the RichHtmlField control is that it’s that control that tells the HTMLEditor whether it should allow the user to insert images, select fonts, etc.
That was a long explanation to say that, to get an HTMLEditor control to work on your page, you need to manually wire it up to a new RichHtmlField in the OnInit method, like this:
protected override void OnInit(EventArgs e)
htmlEditor.Field = new RichHtmlField();
htmlEditor.Field.ControlMode = Microsoft.SharePoint.WebControls.SPControlMode.New;
As mentioned, the RichHtmlField control has a number of properties which you can set on it that will control which functionality is available from the ribbon, such as AllowImages, AllowHyperlinks, etc. You can set those values programmatically on the RichHtmlField object to get the HtmlEditor control to behave as you’d like.