Category Archives: Featured

Custom Field Types in SharePoint 2013 Apps

Synopsis and Key Take-Aways

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.  Unfortunately, this power has never been available in a cloud-hosting scenario such as Office 365.  Things are changing for the better, however, with new capabilities available in SharePoint 2013 Preview.  We now have the ability to provide the same functionality to our end users without running custom code on the server.  With SharePoint 2013 Preview, we can modify the presentation and validation of a custom field (or technically any field) on any form in SharePoint as well as in Views simply via JavaScript.  This is an incredibly powerful capability.  It provides a nice, easy, standard (and supported) way of customizing the end user experience to be more efficient and friendly.

This article introduces the scenario, walks through the end user experience using a sample custom field and then dives into a code-level review of how to implement this new functionality.  The commented source code listing for the required JavaScript is available for download.

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.

Introduction

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:

  1. 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
  2. All of our customizations are happening on the client side via JavaScript.  There are implications to this for your data and business rules.  What happens if a user has JavaScript turned off and therefore your customizations do not run?  What are the implications to the security and validity of your data?  We will touch briefly on custom validation later, but just keep it in mind – it’s not guaranteed to run)

Acknowledgements

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:

image_thumb40


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:

image_thumb20


(Michael Palin would be so proud)

Notice, too, that our field is marked as required in SharePoint and regular field validation continues to function:

image_thumb38


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:

image_thumb36


For the sake of this demo, I’m not actually showing the field value in the View. Instead, I show a JavaScript link that pops up a simple alert when clicked to show the field value:

image_thumb28

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:

image_thumb32

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:

image_thumb34

Technical Walkthrough

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).

The heart of everything we’re doing here is a new property on the out-of-the-box  SPField class (and all of it’s children) within the SharePoint server object model: JSLink (don’t  bother clicking on the link – there is NO documentation worth anything there right now – just a placeholder).  Similar to the JSLink property on SPView, SPField.JSLink gives us the opportunity to specify a custom JavaScript file that will be used to render our field.  Cool.

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:

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Field

       ID="{23d7e8ae-29c3-4f05-ac4a-08bbf2bc2b1d}"

       Name="SiteColumn1"

       DisplayName="Site Column 1"

       Type="Text"

       Required="TRUE"

       JSLink="~site/Scripts/SampleJSField.js"

       Group="Custom Site Columns">

  </Field>

</Elements>

 

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

IIFE

Because we are only specifying a JavaScript filename in our JSLink attribute, and not a particular method to be called, we need some way to actually execute our code.  We do this via an IIFE (Immediately Invoked Function Expression) declared right at the top of the file:

(function () {

    initFieldTypes();

    var r = new JSFieldText("SiteColumn1", viewFunc, editFunc, editFunc, displayFunc);

    r.initField()

})();

 

You could do this different ways, but this is the most concise and easiest.  Basically, in one shot, I’m declaring an anonymous JavaScript function and invoking it.  No magic inside the IIFE itself, it simply calls a function to set up our custom field objects (initFieldTypes), creates an instance of my custom JSFieldText object (passing in the field name and a couple of function objects – more on these later) and then initializes the field.

I’m not going to go into details on the whole initFieldTypes function here.  It’s in the full source listing and it’s a bunch of pretty funky JavaScript at this point.  I plan on cleaning this all up but there’s no sense in doing that until I’m working with RTM bits.  Eventually, I’d like to centralize all of this in a common JavaScript library that can be used by multiple fields, but that will come later.  For now, it was enough just to build out a POC to show that this all works.  A good chunk of the  code in the “Global Code” section of the full source listing is based on some code from http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures but I’m not sure whether I’ll stick with that.  It introduces some complexity and I’m not sure it gets me a lot.  In the short term, however, it filled a void and let me focus on more pressing things.

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:

if (hasValue(this.get_fieldName())) {

      var newCtx = {};

 

      newCtx["Templates"] = {};

      newCtx.Templates["Fields"] = {};

      newCtx.Templates.Fields[this.get_fieldName()] = {};

      //Views are handled slightly differently because of the way they are called by SP

      newCtx.Templates.Fields[this.get_fieldName()]["View"] = hasValue(this.viewCallback) ? this.viewCallback : null;

      newCtx.Templates.Fields[this.get_fieldName()]["NewForm"] = this.renderForNew;

      newCtx.Templates.Fields[this.get_fieldName()]["EditForm"] = this.renderForEdit;

      newCtx.Templates.Fields[this.get_fieldName()]["DisplayForm"] = this.renderForDisplay;

 

      SPClientTemplates.TemplateManager.RegisterTemplateOverrides(newCtx);

}

 

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:

  • Views
  • 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:

/// Function called to render the field in a View

function viewFunc(renderCtx, field, listItem, listSchema) {

    var currentVal = '(null)';

    if (renderCtx != null && renderCtx.CurrentItem != null)

        currentVal = eval('renderCtx.CurrentItem.' + field.Name);

    return "<a href="javascript:alert('This field has a value of: " + currentVal + "')">Show Field Value</a>";

}

 

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:

/// Function called to render the NewForm & EditForm view of the field

function editFunc(renderCtx) {

    var fieldHtml = '<select ';

    fieldHtml += 'id="myNiftySelect" onchange="moveValue('' + this.get_fieldId() + '')">';

    fieldHtml += getSelectOptions(this.get_fieldValue());

    fieldHtml += '"</select>';

    fieldHtml += getStandardInputHtml(this, "hidden");

    return fieldHtml;

}

 

This one is a little more complex than the View, but it is still just building up an HTML string to be returned to SharePoint and ultimately stuffed down the pipe to the client’s browser.  There are a couple of helper functions that you can review in the full source code listing.  In the listing above, all I’m rendering is the select box to present the choices.  The actual field used by SharePoint is handled in the getStandardInputHtml function.  Remember, it renders as a hidden field and I use a simple JavaScript function (moveValue, shown below) to copy the selected value from the dropdown list to the hidden field so it is available to SharePoint.

The moveValue function also handles my custom validation:

function moveValue(targetId) {

    var mySelect = document.getElementById('myNiftySelect')

    var hiddenField = document.getElementById(targetId);

 

    var selectedVal = mySelect.options[mySelect.selectedIndex].text

    if (customValidationPasses(selectedVal)) {

        hiddenField.value = selectedVal;

    }

    else {

        mySelect.selectedIndex = mySelect.selectedIndex - 1;

        selectedVal = mySelect.options[mySelect.selectedIndex].text

        hiddenField.value = selectedVal;

    }

}

 

function customValidationPasses(newValue) {

    if (newValue === "Four") {

        alert("Four is right out!  Counteth thou to THREE and then lobbeth thou the holy handgrenade of Antioch at thy foe, who, being naughty in my sight, shall snuff it.");

        return false;

    }

    return true;

}

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:

//keeping it simple for the sake of this demo code - not really calling a service to get values

function getOptionsFromSimulatedWebServiceCall() {

    return ["One", "Two", "Three", "Four", "Five"];

}

 

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:

var r = new JSFieldText("SiteColumn1", viewFunc, editFunc, editFunc, displayFunc);

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:

/// Function called to render the DisplayForm view of the field

function displayFunc(renderCtx) {

    if (renderCtx != null && renderCtx.CurrentFieldValue != null) {

        var fieldVal = renderCtx.CurrentFieldValue.toString();

        switch(fieldVal)

        {

            case "One":

                return "1";

                break;

            case "Two":

                return "2";

                break;

            case "Three":

                return "3";

                break;

            case "Four":

                return "4";

                break;

            default:

                return "5";

        }

    }

    return '';

}

 

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.

Conclusion

That’s all there is to this.  As I said at the beginning, with it all laid out and explained, there’s not a lot to this and it is pretty easy.  I think that bodes well for this type of customization in the future.  I plan on spending a lot more time on this once the RTM bits are available.  Once I get it all working and cleaned up, I’ll integrate it into my JavaScript series and probably into a SharePoint 2013 version of the CKS:ScriptLibrary project as well.

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

An Introduction to JavaScript

Series Contents

  • Part 1: Introduction and Basics (this post)
  • Part 2: Deploy & Download
  • Part 3: The Client Side Object Model *
  • Part 4: Functions, Objects and Classes
  • Part 5: Avoid the Global Namespace *
  • Part 5: Download & Caching *
  • Part 6: Efficiency & Performance*
  • Part 7: Testing *
  • Part 8: Professional JavaScript Development *
  • Part 9: Error Handling *
  • Part 10: Advanced Topics *
  • Part 11: Security *
  • Part 12: Implementing Business Logic *
  • Part 13: Tools and Resources *
  • Part 14: Wrap-Up *
  • Bonus: JavaScript in SharePoint 2013 *

*: Coming Soon…

Introduction

As the title of this post states, this is an introduction to JavaScript and using it in SharePoint.  It has some good information in it for any JavaScript developer, but it is very basic.  If you are already familiar with JavaScript, go ahead and skim this post or skip it entirely.  There likely won’t be a lot of new material here for you.  If, however, you are just getting started with JavaScript, read on.  You’ll probably learn a thing or two.

JavaScript is not a new technology, and yet it appears to be new to a lot of SharePoint developers.  I honestly don’t know why.  This series is going to take a look at JavaScript from a dev’s point of view and attempt to explain how it can be a very powerful tool in our toolbox.  I’m going to repeat one point there just to make sure you got it: this is a developer’s point of view.  That means no Content Editor Web Part (CEWP, the root of all evil).  It also means Visual Studio, deploying Solution Packages, and generally approaching JavaScript as a coding language (which, after all, is what it is).  If all you want to do is grab a script and toss it into a CEWP, this is not the right place for you.  Please move along.  We’re talking professional developer stuff here.  :-)

Starting right at the beginning – why would we use JavaScript in our SharePoint code when we have a rich server-side API available to us?  That’s an easy one – because not everything can or should be done on the server.  That’s not to say that the server side API is useless.  Quite the contrary – both are necessary to deliver an effective, modern application (whether on SharePoint or not.)  Despite what you may think, and what you may read elsewhere, neither JavaScript nor the server API can solve 100% of the business problems we face.  Too, SharePoint is just a great big ASP.Net application so using JavaScript is not going out on the limb of unsupportability.

In recent years, JavaScript has grown up considerably.  The addition of libraries such as JQuery, Dojo and MooTools have helped make JavaScript to become more popular.  In the SharePoint world, SharePoint’s JavaScript Object Model has brought JavaScript to the foreground.

One quick point here about JQuery.  Nobody anywhere has ever written a single line of JQuery.  There is no such thing.  JavaScript is a language.  JQuery is a library.  We use JQuery to make JavaScript easier to work with, but we don’t write JQuery.  This may seem like a pedantic nit, but it is an important distinction for one reason: there is a wealth of JavaScript material on the web that you ignore at your peril.  If you always look for a JQuery solution, you are almost certainly making your life harder.  That’s not to say that JQuery isn’t a great library; it is.  It’s just not always the answer.  Sometimes a few well-crafted lines of JavaScript are all that is necessary.  There’s not always a need to fall back on JQuery and it’s library of plug-ins.

What Can We DO With JavaScript in SharePoint?

Another easy one.  Just about any UI manipulation we care to write the code for.  This can range from pure eye-candy to something that provides actual business value.  The only times you can’t manipulate the UI are:

  • Content delivered via a plug-in of some type (Silverlight, Flash, ActiveX, etc) (Although, some of these do offer a limited ability to manipulate them via JavaScript )
  • If JavaScript is turned off in the user’s browser

Anything else is fair game, and that is both boon and bane.

DOM Scripting

When you are manipulating the user interface, you are doing what is called DOM scripting or DOM manipulation.  DOM stands for Document Object Model and it is the hierarchical representation of the HTML markup that the browser uses to render your page.  Every object shown on the page (and also those not visible) are represented by a node nested inside the DOM.  Changing the characteristics of those nodes, adding nodes and removing nodes all result in a changed interface being shown to the user – changed, that is, from what the server originally sent down to the browser.

What You Need to Know

At a very basic level, there are a few important things to know about using JavaScript:

  1. JavaScript is an interpreted language and so there are no DLLs that need to be deployed to the server
  2. JavaScript is downloaded to the user’s machine and parsed /executed there.
  3. JavaScript is downloaded in clear-text (though it may be somewhat obfuscated).  This is potentially a big deal as we’ll discuss in Part 12.
  4. Although there is a standard definition of JavaScript (ECMA-262, version 5.1), different browsers will interpret your JavaScript code slightly differently.  This has an impact on testing, as we’ll discuss in Part 8.
  5. Once downloaded, JavaScript files are cached on the user’s machine to improve performance.
  6. JavaScript is case-sensitiveHELLO is not the same as hello and not the same as Hello.
Another pedantic nit here: JavaScript is neither Java nor Java-lite.  Other than some semantic similarities, it has nothing to do with Java.

Your First JavaScript Program

Enough introductory drivel.  Let’s write some code.  Fire up your browser of choice and navigate to any website. Assuming that you’re using a relatively modern browser (IE 7 or later , Firefox or Chrome) open up the developer tools: in IE and Chrome, simply hit the F12 key.  In FF, hold down Ctrl and Shift and hit the K key.

In IE: Click the Script tag and then the Console button below it:

In Chrome, click the Console button:

In FF you don’t need to do anything, the Console is automatically shown:

In the browser/JavaScript console (where indicated in the above screenshots for your browser), type the following code:

alert("Hello World");

Now hit enter.  You should see a small dialog box pop up that shows your message.  Click OK to close the dialog box.

Congratulations, you’ve written your first JavaScript program.  (We’ll revisit each of those Console windows later on in this series).

It’s time to get a little more advanced (but just a little).

Variables

Like any programming language worth it’s salt, JavaScript has variables.  Declaring and using variables is easy:

var myVariable="Hello World";

alert(myVariable);

You can type that in the same Console and you should get the same results.  The variable declaration (“var myVariable=”HelloWorld”) defines a variable which is then referenced in the following alert statement.  At that point the value of the variable (in this case “Hello World”) is used by the alert.  Go ahead and give it a try.

There are a few things that can get tricky about variables, but we’ll cover those later.  For now, here are a couple of rules to remember:

  • JavaScript variables are not typed.  In other words, you don’t declare the data type that the variable will store when you declare the variable, and changing data types is perfectly OK.  The following is perfectly valid, although perhaps not a great practice:
var myVariable="Hello World";

alert(myVariable);  //outputs Hello World, myVariable holds a string

myVariable=345;

alert (myVariable);  //outputs 345, myVariable holds an integer

  • var is your friend.  99% of the time, you always want to preface your variable declarations with the var keyword.  This declares the variable as local to your current scope.  We’ll talk about this more later in part 5.  For now, and until you understand the implications of not doing so, always use var
  • Null – variables are null if it contains an unknown value, which is not the same thing as undefined.
  • Undefinedundefined is a special value in JavaScript.  It means the variable has not been declared (in the current scope – more on that in part 5), or has been declared but has not been given a value.

Functions

JavaScript is organized into functions.  A function is a group of statements organized together in what essentially amounts to a named container.  Here is an example of a function declaration and usage:

//declare the function:

function sayHello(){

    alert("Hello World");

}


//call the function:

sayHello();


 

Passing a parameter to the function is equally simple:

//declare the function with a parameter:

function saySomething(thingToSay){

    alert(thingToSay);

}


//call the function and pass in a parameter:

saySomething("Hello World");

We’ll touch on some advanced function declarations and usage in part 4.

Wrap Up

That’s a quick, high-level tour of the basic stuff you need to know to begin operating in a JavaScript world.  There is obviously a lot more that needs to be covered – or else I wouldn’t have 14 more sections planned :-).  We’ll get to all of that in later sections of this series.  Hopefully this has gotten everyone on the same page.  We’re pretty quickly going to move into the deep-end, so buckle up…

On SharePoint Development

This month at the Tri-State SharePoint user group, I’m beginning a new series of lectures entitled On SharePoint Development.  The idea is to step back a little bit from the how of our daily grind and spend some time talking about what and why.  We will discuss topics that people don’t take the time to think about in the rush to get their day to day jobs done – more of a thought-provoking session than a “here’s how you do it”  (although there will be demos and discussions of how to accomplish many of the tasks discussed).  The goal is to make us better SharePoint professionals by improving our work habits and making us more efficient.

A former boss of mine used to call this working “on the business” instead of “in the business”.

This is part of a larger effort I’m kicking off in the new year related to this topic.  I’m planning on video taping many of these sessions and posting them, along with white papers/articles, etc.  Here’s an idea of the types of topics I plan on covering:

  • Declarative vs. Programmatic – creating SharePoint artifacts
  • Programming SharePoint with JavaScript – why, where and how
  • Cross-Cutting Concerns
  • Tool Use – “What Does It Cost to be a SharePoint Dev?”
  • Deployment and Installation – batch files and scripts?  Really?
  • VS Project & Solution Design
  • Testing – UI, Unit, Automated, etc – (covering the why and where, not so much how)
  • Team Dev – when the team includes end users
  • Performance, and why it doesn’t matter
  • Application building blocks in SharePoint
  • “Code is Not Evil”
  • Naming Standards and Pretty Code
  • Consistency – not a Hobgoblin
  • Code Reviews – check your ego at the door

While I typically dislike announcing things when I don’t (yet) have anything to show, I needed to put this stake in the ground and get this started.  Stay tuned for more information.