Synopsis and Key Take-Aways
Note that as of the initial publication of this article (October 2012), this is based on the SharePoint 2013 Public Preview. Once I can download RTM I’ll look to revisit this and update the article as necessary.
Custom field types in SharePoint provide the ability to customize all aspects of SharePoint form fields– from how they are displayed, to how values are validated to how values are stored within SharePoint and a couple of other things along the way. They provide significant capability for enforcing business rules and providing a much more user friendly experience than what is available via the out-of-the-box field types (single line of text, yes/no, date/time, user, url, etc.)
Unfortunately, this power and flexibility is simply not available in a cloud scenario such as Office 365 because they require that files be deployed to the server file system which you can’t do in a cloud solution. For the 2010 release of SharePoint, there have been various attempts at simulating custom field types in a cloud scenario, but all have suffered from varying degrees of fragility or other problems.
Fast-forward to SharePoint 2013 and Microsoft has made things much easier for developers and much less fragile all around with regard to custom field types. For the first time, it is possible to truly get most of the value of custom field types in a cloud scenario such as Office 365 or an on-premises scenario (without all of the work of doing it the old way). Notice that I said most of the value. There are some things that are still not possible and two major caveats of which you must be aware. First the caveats:
- Even though we are building things which look and act like custom field types, we are not technically building custom field types. We are technically just customizing the rendering and validation of the out of the box field types. More on this later; just remember it for now
Before going any further, I need to give credit where credit is due. Andrew Connell and I hacked up the first portion of this together. I took the rough POC AC and I had pulled together that almost did everything we wanted, finished it off and cleaned it up to produce the samples in this article. Keep an eye on AC’s blog as he’ll be posting a follow-up article taking some of this in new directions.
Overview of the Solution
With all of that said, let’s see what it is that we’re going to get at the end of this. Here are some screenshots and descriptions of what we’re going to build out in the rest of this article:
The New Item Form
In this example, we’ve customized the rendering of our custom field:
Site Column 1 is our custom field. Technically, it is just a simple text field. Without our customizations, it would render as a textbox. Our customizations change it’s rendering to a dropdown list.
The choices available in the dropdown (One through Five) are added dynamically. In a real world scenario, these could come from a web service call. To keep things simple and focused here, I’m simply hardcoding an array. You’ll see when we get to the code how simple it would be to make this truly dynamic.
We’ve also added some rudimentary validation. For the sake of this demo, FOUR is not a valid choice:
(Michael Palin would be so proud)
Notice, too, that our field is marked as required in SharePoint and regular field validation continues to function:
One of the things I’d like to play with in a later version of this is the possibilities for additional validation via CSOM and perhaps even some event receiver work to provide additional server-side validation.
Display in Views
Once we’ve entered a legal value, our item is shown in a SharePoint View. We also have the opportunity to customize the rendering here as well:
The Display Form
Again, for the sake of this demo, I’m customizing the presentation of our field on the Display form as well. Instead of showing the actual value, I show it’s numeric equivalent:
The Edit Form
The Edit form looks largely identical to the New form (internally, it’s actually rendered via the same code). The only difference is that we have to make sure that the current value of the field shows as selected in the dropdown:
Now that we’ve seen what we’re building, let’s dive into how to make it all work. Once you’ve figured it all out, it’s actually pretty easy. (Figuring it all out, though, that was a royal PITA, especially during a beta cycle).
From our SharePoint 2013 App (or, really, any SharePoint 2013 solution), we add an attribute to the Elements file that defines our custom Field to specify the JSLink value:
The SampleJSField.js file will now be used to render our field wherever it is used. The full SampleField.js file is available at the end of this article for your reading pleasure..I’ve added some comments to explain what is going on, but the following sections spell out the highlights
Registering Our Custom Rendering
I will, however, focus on a few key areas within the initFieldTypes function. The first is where we actually override the default rendering and tell SharePoint to use our custom rendering. This is done via the initField function on the JSFieldText object:
This code sets up an object hierarchy in a manner prescribed by SharePoint 2013 and registers the new functions to render each of our possible views of this field:
- Display Form
- Edit Form
- New Form
The last line of the snippet is what actually registers our custom handlers with SharePoint.
Views are handled slightly differently because of how they are called internally by SharePoint. For Views, we simply pass the callback that was supplied in the constructor of our field. Note that we do check for null and undefined via some helper functions. If we set the View or any of the Forms to a null or undefined value, SharePoint will use it’s default rendering.
The Forms all use a function on our JSFieldText object because we need to do a little processing before invoking the callback.
Once the callbacks are registered, they’ll be called by SharePoint instead of the default rendering mechanisms.
One of the things that you’ll notice about all of these callbacks is that we’re not dealing with HTML objects. In each case, we need to return the actual HTML text to render our desired UI, so we’re doing a lot of string manipulation. That’s just the way SharePoint expects things to be, so we just run with it.
Technical Details: Views
The View callback is a simple method that modifies the value written into the standard SharePoint View as we saw in the screenshots above. Here’s the code for that:
Notice that the name of our function (viewFunc in this case) was the value passed into our JSFieldText constructor earlier. The other callbacks operate the same way. Note also the use of the eval statement in there. I’m not thrilled with that and would like to find a way around it but haven’t come up with anything yet.
Technical Details: Edit Form
The Edit Form callback is used to render the field on an Edit Form. Here’s the code for the sample I built:
The moveValue function also handles my custom validation:
There’s a fair amount going on in the editFunc function, but none of it is very complex. This is another area I’d like to work on tweaking a bit.
As I said before, for the sake of this demo, I have hardcoded in an array to provide the choices for the dropdown:
If you needed to make this dynamic, simply change the code in that method (and probably its name, too) to do whatever you need.
Technical Details: New Form
The New Form rendering is actually handled by the editFunc function. Notice back in the IIFE when we create the JSFieldText object that we pass editFunc in twice:
The first one is actually the New Form callback. If you needed to render your field differently on the New Form, simply pass in a unique callback here.
Technical Details: Display Form
Last but not least is the Display Form. Remember this shows the numeric representation of our field’s value (kind of lame, I know, but I wanted to show something different for each type of rendering and this was the best I could come up with). The displayFunc function handles this for us:
The Future’s So Bright…
I’m quite excited about the possibilities being opened up for developers with changes like the JSLink property in SharePoint 2013. While a number of folks are bemoaning the move to the cloud and the changes that brings, I’m quite bullish on the whole thing. Sure, there are some things I don’t like, but all in all, as a developer, I’m happy. At least in the 2013 release, I don’t really lose anything very important for my on-premises deployments and I pick up significant ground in my cloud implementations. A win all around.
Specifically for custom field types, I see this capability as incredibly powerful. A nice, easy, standard (and supported) way of customizing the end user experience to be more efficient and friendly opens up a lot of possibilities. I predict a small segment of the app store will be based around custom fields utilizing this capability.
Comments and ideas for additional functionality are welcome. I do realize that a lot of the code in this needs to be cleaned up and like I said, I’ll get to that with the RTM bits. If you have specific comments about something that doesn’t work, or could be refactored to make this better, I’d specifically like to hear those.
Source File: SampleJSField.js.zip