CSR on Steroids and the Amazing Technicolor Text Boxes, or CSR by Type

First things first, I want to apologize, because what I’m going to build in this post is pretty hideous. I’m going to introduce the concept of hooking up SharePoint CSR by type, rather than by internal field name (as most examples show). In this post, I’m going to show how to do CSR by Type, meaning override all fields of a given SPFieldType.

By way of background, yesterday I was trying to override the Client-side Rendering (CSR) of a Url field to allow it to take non-standard protocols like notes://. I didn’t feel like creating a site column so I applied it to the OOB site column called Url. So I setup my overrides like so:

Here I’m overriding the rendering for the field called Url in all forms and views, right? Not so fast sparky! This worked a little too well. My override was getting called for other fields of type SPFieldUrl on the page that weren’t named Url. Ugh! Stepping through clienttemplates.js in the debugger, it quickly became apparent what was going on. In the fields object, you can specify CSR by internal field name, like I’ve been doing in previous posts in this series, but you can also specify CSR by type of field (using the client-side field type, so for instance Text for SPFieldText). This replaces the default rendering for all fields of that type.

That’s actually pretty cool, but the problem with it is that if you have a field whose internal name is the same as a field type, there is no way for you to override just that field. Bad Microsoft, programmer no donut! The rest of this post is going to be a quick demo I put together to demonstrate this functionality. I haven’t seen anything in the documentation for CSR, or any examples, that explain this functionality. Of course, the documentation for CSR is pretty thin.

I’m going to override the rendering for all fields of type SPFieldText. To do that, I’ve implemented the following CSR code:

And because my CSS is scrunched up in a single line of code, I’ve broken it out here and formatted it for better readability:

There’s nothing special about this CSR, it’s just using the same techniques I’ve been using throughout this series. The only difference is that it’s overriding Fields.Text, which isn’t the name of a field but rather the client-side name of a field type (SPFieldText).

As usual, I still need to get the JavaScript injected into the page. To do that I’m going to set the JSlink property of the Title field. Since every list has a title field, this effectively overrides the rendering of text fields in every form or view in the site collection. If you haven’t read through this series, you can accomplish this using the utility page from the previous post Setting the JSLink Property of a Field Using JavaScript.

With that done, if I visit a contacts list in my site collection, I am greeted with this lovely display:

CSR by type: Technicolor TxtBoxes View

Now kids, don’t try this at home, this is for demo purposes only. The forms look similar, but I haven’t shown them here because I really don’t want to be held responsible for giving my readers headaches, or worse yet seizures.

Specifying CSR by type is a cool technique, but with great power comes great responsibility. For instance, my first attempt screwed up the callback to registerGetValueCallback, so it always returned an empty string. This caused the form to fail to submit, because the required field title didn’t have a value, but since I haven’t implemented validation in my simple example, no error message is displayed to the user. You just click the button and nothing happens. I probably don’t need to tell you this, but you’re not going to win any medals for breaking every form in your site collection. I’ve fixed that of course, but this still isn’t a complete example. At a bare minimum, it should call registerValidationErrorCallback to show validation error messages to the user.

The takeaways from this are:

  1. You can override the rendering by registering CSR by type or internal field name.
  2. If the type and the internal field name are the same, that’s a problem, so don’t do that.
  3. And finally, don’t use OOB site columns that have an internal field name that is the same as a field type in any CSR solutions.

One final caveat is that while this CSR did override the title field in my contacts list, in SharePoint online it did not override the title field in several other lists. It does override all other text fields in all lists. I’m not sure why, I’d need to step through clienttemplates.js again to figure it out. I haven’t seen that behavior on any on prem version of SharePoint.

This post started off as an answer to a question on StackExchange, but I figured it was worth expanding on a bit.

Leave a Comment