This project has moved. For the latest updates, please go here.

SPEasyForms is a Rapid Application Development (RAD) tool for applying jQuery constructs to Out of Box (OOB) SharePoint forms without necessarily knowing anything about JavaScript or HTML or CSS. You configure SPEasyForms through a drag and drop IDE-like list settings page, which is available on the list ribbon or as a link on the list settings page of compatible SharePoint list types (currently all lists except Surveys and Discussion Boards). The things you can configure fall into 3 broad categories:

  • Containers - the ability to organize fields in a form in some way; current implementations include:
    • Tabs - an implementation of jQueryUI tabs
    • Accordion - an implementation of jQueryUI Accordion
    • Columns - the ability to put fields into 2 or more columns instead of one per row (technically, one or more, but one column doesn't really buy you much)
  • Conditional Visibility - control when a column is visible based on the SharePoint group membership of the current user and/or the current value of another field in the form
  • Field Control Adapters - modify the controls users see in the form to input data; current implementations include:
    • Cascading Look Ups - join two look up fields such that the values available in one look up are trimmed based on the value selected in another look up
    • Autocomplete - provide type ahead functionality in a text field based on values pulled from a field in another list on the same site

The rest of this user manual will consist of an Overview section (system requirements, installation, and a laundry list of UI buttons and views), and sections for Containers, Conditional Visibility, and Field Control Adapters. In those last 3 sections, we'll follow a scenario (i.e. state some basic requirements and how those requirements can be satisfied using SPEasyForms). This scenario will be a Contacts list with multiple content types (Contact and Employee).

1. Overview

People learn differently. This section is primarily reference information. Some people want to scan this first to get an idea of what's available for the 10,000 foot view. Others want to jump right into using the thing and go back to the reference material on an as needed basis. I've chosen to put this up front in my document, but if you fall into the latter group and you already know how to install a sandbox solution, you can certainly skip this section and jump to section 2. Containers.If you just need help installing it but then want to jump in, read the next two brief sections and then skip to section 2. Containers.

1.1 System Requirements

SPEasyForms has currently been pretty well tested on Office 365 and moderately tested on SharePoint 2010 and 2013. If you want to try it out now on 2013 or 2010, feel free and post any issues you encounter to the discussion board and we’ll address them when we can. There are no plans to support SharePoint 2007.

1.2 Installation

In order to install SPEasyForms, you must have sufficient privileges to install a sandbox solution and activate a site collection feature (that means you need to be an SCA).

Anyway, to get started, download the latest recommended release from https://speasyforms.codeplex.com and follow these steps to install it:

  1. Go to the root site of your site collection and go to Site Settings –> Web Designer Galleries –> Solutions.
  2. Click the Upload Solution button in the ribbon.
  3. Browse to the SPEasyForms.wsp file you downloaded from CodePlex and hit OK.
  4. When the upload finishes, click the Activate button from the ribbon.

Now that wasn’t too painful, was it? To confirm that it appears to be working, go to a list in your site collection and look for a button in the Settings panel of the List, Libraryor Calendar ribbon labeled SPEasyForms:

image

Click on the the icon and you should see the SPEasyForms Settings page, pictured in the next section.

If you've gotten this far, and the settings page looks OK, the thing is installed. If you've already encountered a problem, go to CodePlex and open a new thread in the discussion board with your issue. I generally try to respond pretty quickly, and as I build up a list of frequently encountered issues I'll update this document with a troubleshooting section.

1.3 The List Settings Page

image

The list settings page is pictured above. It is comprised of four parts:

  1. Bread Crumbs – starts with the name of the list, which is a link back to the page that brought you here, followed by the page title, and optionally followed by the current view. Note: the bread crumbs are currently missing in SharePoint 2010. At some point I will figure out where to put them and how to get them there and I'll put them there.
  2. The Ribbon – most of the high level functionality is controlled by buttons organized on the ribbon. Each button will be described in the next section.
  3. Properties Pane – on the left-hand side of the main content area, this is where you configure individual fields in the form.
  4. Main Content Area – when the page first comes up, this shows a WYSIWYG (what you see is what you get...well, mostly anyway) on the right-hand side of the main content area. This provides a visual representation of the form as currently configured. You can change the view to display a list of field visibility rules or field adapters using buttons on the ribbon.

1.4 Ribbon Buttons

This section is just a laundry list of the ribbon buttons intended primarily for reference. Most of the functionality of SPEasyForms is exposed through the following ribbon buttons:

image

Saves the configuration as JSON in a text file in the Site Assets library of the same site where the list resides. This button is disabled until there are changes that need to be saved.

image

Return to the page that brought you here, discarding any uncommitted changes. If you do have uncommitted changes, you will be presented with a confirmation dialog.
image If there are multiple content types for the current list, this drop down lets you choose which one you are currently editing. The details of multiple content types will be explained later.

image

Add a container to the form for organizing fields, like tabs, accordion, or multi-column table.

image

Undo or redo a change. Undo is only enabled when there are uncommitted changes that have not be undone. Redo is only enabled when you have undone at least one change.

image

Show the visual representation of the form as currently configured in the main content area. This is the default view.

image

Show the list of conditional visibility rules in the main content area. You are switched to this view automatically when you add or edit conditional visibility rules.

image

Show the list of field adapters in the main content area. You are switched to this view automatically when you add or edit field adapters.

image

Expand or collapse the containers in the properties pane. When collapsed, only the title shows, otherwise all field collections and fields show. You can also collapse individual containers in the properties pane by double clicking on them.

image

Export the configuration file. This just opens up the JSON text file containing the configuration in a new browser window. This button is disabled if you have never saved a configuration for the current list or you have uncommitted changes to the current configuration.

image

Import a configuration. This just opens a dialog with a large text area where you can paste JSON text. It is primarily intended to backup a configuration or copy the configuration between two similar lists (i.e. a contacts list in test to a contacts list in production). Muck with the JSON manually AT YOUR OWN RISK. The import completely overwrites the current configuration, but is not committed until you hit save and can be rolled back with undo. This button is disabled when you have uncommitted changes to the current list.

image

SPEasyForms uses a cache in the browser to store context information about the current site and it’s lists for the duration of the browser session. This can be confusing because the form will not reflect changes you have made to the list settings in another window. To get around this, click this button to clear the browser cache and reload the page. Note that this cache is different than the cache the browser uses to cache pages and images, clearing that cache will have no affect on SPEasyForms.

image

Reload the current form in Verbose mode. This primarily shows fields that don’t exist in the current content type and highlights them in red with a tool tip saying they may have been deleted. Normally, these fields are hidden and assumed to be valid in another content type. Also, when in verbose mode, SPServices methods that support the debug parameter are run with debug true, so they popup messages on errors (normally they fail quietly).

image

Present a dialog with the version and license for the currently installed software. Also provides credits and license terms for third party libraries used/distributed as part of SPEasyForms. SPEasyForms is distributed under the MIT License (MIT), and so far all third party libraries that it uses are also distributed under the MIT License (MIT) or are public domain.

image

Brings up this user guide in a separate browser window.

1.5 The Properties Pane

The left-hand side of the main content area is the properties pane. Most of the configuration of SPEasyForms is done from the properties pane.

image

It contains a gray box per container, with the container type as the title. You can collapse all containers (i.e. show only the title) using the buttons on the ribbon. You can also collapse individual containers by double clicking on the container.

A container contains one or more field collections, which are just logical groupings of fields that are used by the container in a container specific manner. In other words, the tabs container draws one tab per field collection, and puts the fields in each field collection on the appropriate tab. The field collection title is also used as the tab name in the form. The columns container creates a table with X columns where X is the number of field collections, and puts the fields in each field collection on the appropriate column, and the field collection title is not displayed at all in the form, it is only displayed on the settings page. You can also collapse individual field collections by double clicking on the title of the field collection.

It may seem like I’m spending a lot of time talking about collapsing, but it is important because you move fields between containers and collections, and reorder fields within a collection by dragging and dropping them. When you have a lot of fields, and containers, and field collections, and you want to move something from the bottom of the form to the top, it is a lot easier if you collapse stuff that is between the two containers you’re currently working with. And if you don’t have a lot of fields, you probably don’t need something like SPEasyForms, although it can still be useful if you have requirements like conditional visibility.

The containers also have buttons that have specific meanings depending on their context/scope (i.e. the buttons are generally to the right of what they configure or the title of what they configure, and can be for configuring the container itself, a field collection, or an individual field). These buttons are described in the following table:

Button Scope Description

image

Container Add one or more field collections.

image

Container Delete this container, all fields are returned to the default form. There is no confirmation, but undo works just fine.

image

Field Collection Change the title of the field collection (i.e. tab name).

image

Field Collection Delete this field collection, all fields are returned to the default form. Again, there is no confirmation, but undo is your friend.

image

Field Configure field visibility rules for this field.

image

Field Add or configure the field adapter for this field. If there are no field adapters available for a particular field type, this button will not appear next to fields of that type.

Note to self: must find graphic artist. I’m no artist myself, and it's amazing how quickly you can run out of useful icons when you’re trying to use the built-in jQuery UI icons for anything other than say navigation. I can certainly make simple icons, but it is time consuming and not high on my priority list, so for now I'll live with using the built-in icons and be content if different buttons have different icons even if the icons don't necessarily convey much about the purpose of the button. The buttons do have hover tool tips, so if you're not sure what they are hover over them.

1.6 Limitations

SPEasyForms is intended to work on the OOB new, edit, and display forms for most list types. It does not work on Discussions or Surveys, and there are other list types it hasn’t been adequately tested on. It also does not allow you to configure content types based on folder. Folders rarely have enough metadata to require such a solution, but the bigger issue is that Microsoft subclasses folder for some pretty strange content types (like document set or OneNote document) that are so different from other OOB list types that it would nearly double the code to deal with them.

The reason for these limitations is fairly obvious, in that SPEasyForms modifies the OOB forms by directly manipulating the Document Object Model (DOM) and/or applying CSS to DOM elements. That means it needs to make some assumptions about the structure of a document. But SharePoint, and particularly SharePoint designer, allow you to customize the DOM to your hearts content. And in the case of lists like Survey, Microsoft has modified the DOM themselves enough that the OOB form does not look much like the DOM for a generic list. For instance, SharePoint normally produces forms that consist of a table with a row for each field. But you can modify the XSLT for a DataFormWebPart such that the fields are displayed as floating divs with fixed positions and there is no table whatsoever. And there's technically nothing wrong with that, but you will certainly have made the form unusable by SPEasyForms because you've broken the parser. The rest of this section will attempt to describe the DOM elements and structure that SPEasyForms depends on. If you are not going to muck with the structure of the form at all, you don't really need to worry about these details.

So the basic constraints are as follows:

  • The form should be in a table with the CSS class ms-formtable.
  • Each row should contain a single field, and be comprised of two table cells with the CSS classes ms-formheader and ms-formbody in that order.
  • The row should contain somewhere in it’s source the texts [fieldname=”<the field display name>”], [fieldinternalname=”<the field internal name”], and [fieldtype=”<sharepoint field type>”]. The names in these expressions are case insensitive, the values are not.
  • The actual name of the ASPX page should contain new, edit, or disp, case insensitive, and it would be helpful if it was actually the new form if it contains new, the edit form if it contains edit, etc.

These constraints are all met by most OOB list forms. They are not met, however, by SharePoint designer generated custom forms, unless you do some manual messaging of the generated XSLT. I have updated the DOM parser such that it can deal with SharePoint designer generated forms assuming you haven't mucked with the XSLT too much. The constraints for designer generated forms are as follows:

  • The form should be in a table (I'll add the class ms-formtable to it if not already present).
  • Each row should contain a single field, and be comprised of two table cells with the CSS classes ms-formheader and ms-formbody in that order.
  • The row should contain somewhere in it’s source a NOBR element that contains the display name of the field. We'll look up the internal name and type using the list schema.
  • The actual name of the ASPX page should contain new, edit, or disp, case insensitive, and it would be helpful if it was actually the new form if it contains new, the edit form if it contains edit, etc.

OOB designer generated forms meet these constraints. If either of these lists of constraints are met by your forms, they should work with SPEasyForms.

Anyway, now that you’ve got it installed, and I've finished the overview, it's time to start looking at our scenario and take it for a spin.

2. Containers

As mentioned previously, the rest of this document is going to follow a scenario, starting with a list and some requirements, and showing how SPEasyForms can be used to satisfy those requirements.  This section will describe the list that will be the starting point for our scenario.

I generally start regression testing with a Contacts list, because that's an OOB list type that has enough fields that the form looks pretty bad as is and could use some restructuring. In order to demonstrate all of the current capabilities of SPEasyForms, I'm going to make the following changes to the list:

  • Turn on allow management of content types in the list settings.
  • Create a site content type called Employee using Contact as the parent content type, add the following columns to it, and add it to the list content types:
    • EmployeeId - single line of text.
    • HireDate - date.
    • EmergencyContact - enhanced rich text.
    • HomeAddress - enhanced rich text.
  • Create the following list columns, choosing 'Add to all content types' when you do:
    • Code - a single select choice field (Blue, Green, and Red for the allowed choices).
    • SalesRegion - look up to a list called SalesRegion where the title field has a display name of SalesRegion.
    • SalesDivision- look up to a list called SalesDivision where the title field has a display name of SalesDivision.
    • SalesState - look up to a list called SalesState where the title field has a display name of SalesState.

These last 3 fields are to demonstrate cascading look ups, which we won't get to until section 4. Field Control Adapters. I'll describe the reference lists in more detail when we get to it, so if you're not sure how to set them up you can skip it until then. However, if you've ever setup cascading look ups for SPServices before, it's just like that because I'm using the SPServices library to implement cascading look ups.

Anyway, now that we have all of this stuff configured, go to the new form for an Employee:

image

I know what you're thinking...prrreeettty! That brings us to the first requirement for our scenario:

  1. Make the form pretty.

Now I’ll be the first to admit this isn’t a very good requirement, but if you’ve been working in this business for a while you probably recognize it as a pretty common one. So you resist the urge to call the customer stupid and start pitching ideas. Maybe we could organize some of the fields into tabs? You start white boarding and come up with a design that the customer seems to like. Maybe pretty is going a bit far but it's hopefully more visually appealing and functional at least. That’s what containers are all about so lets configure one.

2.1 Columns

The columns container just lets you organize fields into two or more side by side columns (technically it can be 1 or more, but 1 column doesn’t really gain you much). To add a columns container:

  • Click the Add button.

image

  • Select Columns from the drop down list and click Add.

image

* Note: for this particular container, these column names are not used in the form at all, they are only displayed in the editor, so use whatever you want; I usually just put in column numbers.

  • Enter column names one per line and hit OK.

The settings page should now look like this:

image

The first thing to notice is that nothing really changed on the WYSIWIG side of the form. You might think you just need to scroll down and you’ll see columns, but trust me nothing changed. This is because containers that have no fields are hidden. This is a trick that you can use to your advantage when configuring multiple content types for a single list, but I’ll save that discussion for the end of this section.

In the properties pane, however, you’ll now see 2 containers, the second one being a columns container with two empty field collections. Once you have moreimage than one container, you can reorder the containers via drag and drop. In the picture to the right I’ve dragged the columns container above the default form (after collapsing all containers, I might have mentioned how to do that earlier). There’s still no change to the WYSIWIG, to see it there you have to put some fields in at least one of the two field collections so lets start doing that.

First expand the containers. Now you can drag fields from the default form and drop them on the field collections in the columns container. You can drag fields from any field collection to any other field collection, or even reorder the fields within a field collection via drag and drop. You can only drag fields one at a time, which can be a little tedious but you have to admit it's still easier than coding a custom solution. I may try to implement a multi-select drag and drop in a future version, but for now it's one at a time. I’m going to put 2 or three fields in each column, after which my settings page looks like this:

image

Now there are some changes to the form view. I have 5 fields arranged in 2 columns followed by the default form. Of course the form view isn’t really a WYSIWIG, it's just structurally close. It doesn’t draw any input controls, the boxes on the right-hand side are just the form body table cells with some CSS to give it a border, which becomes apparent when you see the columns container in the form view, because in addition to moving the fields into a multi-column table, the columns container moves the field label into the form body cell placed above the input control to save horizontal space. It also applies some CSS to shorten ms-long input controls, when and only when they’re on a columns container, again to save on vertical space. To see what it really looks like you need to open up the new form on the list again, but first hit the save button in the editor or you’ll be utterly underwhelmed by the dramatic lack of changes to the form. Once you’ve saved, the new form should look something like:

image

I would be lying at this point if I was to say that we’d achieved anything even close to pretty, but we’re making some progress and it took a lot less time to configure it then it took to write this section. But the real power of containers is that you can put as many as you want on a page and mix and match them any way you want. To demonstrate, add another columns container to the form with 4 columns, drag it just below the first columns container, and add the four fields Code, SalesRegion, SalesDivision, and SalesState to it, one per field collection. Save it and refresh the new form and it should look something like:

image

Again, its not particularly sexy, but it's starting to show some potential. With just the columns container I can create a wide variety of grid view type layouts, limited only by the horizontal size of the controls and how wide I’m willing to let the form get. And let’s face it, everyone knows most user’s have a display with more horizontal real estate than vertical and nobody likes to scroll (at least maybe everybody except the guys at Microsoft who wrote the first SharePoint forms ;). On a side note, I might be giving away my Java background throwing around terms like grid view layout, but I could have just as easily thrown out C/C++, maybe MFC, or even ADA terms. OK, so I’m not so young, but I digress.

Anyway, the basic idea behind containers is to organize fields in a way that maximizes screen real estate, and the Columns container provides some ability to do just that. But the other containers, tabs and accordion, have even more potential to maximize screen real estate, so lets quickly see how they work. Since we hopefully have the basics down, I’m going to move a little quicker through those sections.

2.2 Tabs

Tabs are configured in the same way as columns, in fact so is accordion, so I'm not going to go into the same step by step description of how to configure them like I did for columns, I'll just give you a table of tab names and the fields to put on each tab and then show what the editor looks like if you configure it correctly. The tabs I'm going to configure look like this:

Tab Name Fields
Address

Address

City

State/Province

ZIP/Postal Code

Country

Phone

Business Phone

Mobile Number

Fax Number

HR

HR  

Leave the HR tab empty for now. Once you've configured these tabs, the editor should look like this:

Note that the tabs are fully functional, and that the HR tab is not displayed at all in the WYSIWIG. Just like empty containers are hidden, generally empty parts of containers are hidden too. Also note that I snuck in a change and moved the field content type to one of the columns containers.

2.3 Accordion

The accordion is more or less just like tabs except that headers are stacked vertically taking up more vertical real estate, and all content areas are collapsed initially taking up less vertical real estate. This makes the accordion more appropriate for optional fields of lesser importance. Configure the accordion as follows:

Header Name Fields
Notes & Attachments

Notes

Attachments

E-Address

Email Address

Web Page

HR  

Again, leave the HR content area empty. Once you've configured the accordion, the editor looks like:

 

Now beauty is in the eye of the beholder, but I still think pretty is a stretch. For pretty, you're going to need a designer, I'm a coder. Or at least tell me exactly what you want, I can make it work, my short comings are that I think functional is pretty. I used to do UI design with intentionally hideous color schemes in order to force the customer to tell me what they want. I kind of stopped doing that when one time they just said ship it.

Anyway, I think we've achieved the goal of making a messy form more visually appealing and functional. If you disagree, move some stuff around, add some containers, make it your own.

So it's taken me hours to write this document so far. It's probably taken you 30 minutes or so to read it up to this point, depending on a number of factors like attention span, and weather your trying to follow along with a SharePoint site open in another tab, etc. But once you get familiar with the interface, you could configure a form like this from scratch in 2-3 minutes tops. Being able to satisfy a requirement as vague as 'make the form pretty' in a few minutes is pretty nice.

2.4 The Finished Product...Almost

We're pretty much done with the basic structure and layout of the form. Go ahead and go to the new form for your list and it should look like this (assuming you've saved your changes of course):

image

So what's with this ...Almost crap? OK, I know I'm not fooling anybody, you can all see the next header, I've dropped plenty of hints, and we haven't configured any of the fields specific to the Employee content type. If you go back to the list and open the new Employee form, you'll see the Employee specific fields at the bottom of the form drawn just the way SharePoint would usually draw them. That's because they are on the default form, and in our SPEasyForms configuration we put the default form at the bottom of the page. If you drag the default form to the top of the containers in the editor, save your configuration, and reload the page you'll see these fields are at the top of the form. You may want to leave some fields on the default form; you may not. If you don't, read the next section which will tell you how to configure multiple content types.

2.5 Multiple Content Types

If you skipped the overview and you've just been following along without being particularly inquisitive and clicking on stuff I haven't told you about yet, you may have noticed that at no point in following this scenario did you see the Employee specific fields anywhere in the editor. That's because when the editor loads it brings up the default content type. But given your recent experience with opening the new Employee form, you should understand some things about how SPEasyForms deals with multiple content types:

  1. There is only one configuration per SharePoint list.
  2. Fields that commonly exist in multiple content types are only configured once, and appear in the same place in the forms of all content types.
  3. Fields that don't exist in the currently selected content type are not displayed in the editor and skipped when transforming a form without raising any kind of error.
  4. As previously mentioned, containers or parts of containers that don't have any visible fields for the current content type are hidden.
  5. Finally, to change the currently selected content type, find the content type drop down on the ribbon and select the one you want.

And wait...and wait...OK, should be done by now unless SharePoint is particularly slow where you are. The wait is because the first time a content type is selected I fetch information about it from a web service. There is no visual indication of what I'm doing, the screen just freezes for a few seconds. I should probably fix that with some kind of spinning/whirling thing in a future release, but for now it's good enough for me.

Once the web service returns its data, any fields from the previous content type that don't exist in the new content type are removed from the editor, and of course any fields specific to the new content type are added to the editor. If they've never been configured before, they are added to the default form container. If you don't see them, you might need to expand this container. Once the data has been fetched, it is cached in the browser session so there is no wait switching back and forth between content types, but not in the browsers page cache, so clearing the page cache will have no effect. If you modify the content type in this or another browser after it has been cached, to see your changes in the editor you need to hit the clear cache button in the ribbon, which will reload the page (save any changes first).

The configuration JSON structure has room to easily expand to allow the configuration for a given content type to be ‘divorced’ from the list configuration allowing multiple configurations for the same list, one per content type, but I haven’t decided if that is even desirable yet. If I get requests for it or I decide it would be useful for me, I might add it in some future release. But I decided to implement multiple content types the way I did, not because I‘m lazy, but because of my personal experience with how I use multiple content types in a single list. Usually, I put multiple content types in the same list because they are more the same than different. If two content types are mostly different (i.e. share few or no fields), I generally put them in different lists anyway, it's not like they can usefully share many views. And if they’re mostly the same, I want the forms to be mostly the same.

So switch to the Employee content type in the editor now and you should see the Employee specific fields appear in the default form container. If you don’t, try expanding the default form container. Now drag a couple of these fields onto the HR tab, and the other two onto the HR content area of the accordion. Save your changes and refresh or reopen the new Employee form, and you should now see the HR tab/content area with the employee specific fields on them. Go back to the new Contact form and you should still see the HR tab and content area are hidden. So your new Employee form should look something like this:

With the following caveats:

  • I didn't tell you which fields to place on which HR content area, so yours may not look quite like this.
  • I opened the HR tab and expanded the HR content area on the accordion before taking the snapshot in order to fully show what changed. The form loads with the Address tab selected and the accordion fully collapsed to conserve vertical real estate.

You now know everything you need to know about configuring multiple content types in SPEasyForms, we are truly done with modifying the form structure, and thus we are done with containers.

2.6 Validation

So what happens when a required field is on a tab and the user hits submit without providing a value? 

  • First, any tab that has a validation error is highlighted by giving the tab header a red border.
  • Also, the first tab with a validation error is automatically selected.
  • The OOB validation messages that are normally displayed with a field are still displayed with the field.

Accordion works the same way, and Columns does not need any special logic for this because it does not have any hidden content areas.

3. Conditional Visibility

Note: this is NOT a security mechanism. It is appropriate for workflow-type visibility requirements. If disclosure of fields to the wrong people would be considered to be any kind of a security breach, no front end solution is appropriate. A clever/technically savvy user can get to fields that are supposed to be hidden from them using the JavaScript debugger or DOM inspector, or in SharePoint 2010 even just viewing source in the browser. Even if I could fix that, they could write their own JavaScript, call the web services, and view the raw data.

With that caveat out of the way, I implemented containers first when I started working on SPEasyForms, because it’s the lowest hanging fruit of forms customization. Pretty much every time I’ve worked on a form for a customer, the list of fields quickly got long, the form started looking pretty bad, and somebody threw out the old ‘make the form pretty’ requirement in some guise or another.

Second on the low hanging fruit list in my opinion is conditional visibility. I get a lot of requirements like I don’t want people in group X to see the phone number field. Or I only want people in group Y to see the phone number field. Or the address field should be on the edit form but not the new form. Or even I want people to be able to edit the title field if A=B, but it should be read only when A=C, where A is another field in the same form. Conditional visibility in SPEasyForms is intended to satisfy all of these requirements and more.

And they are all pretty simple. Most of the time you can get away with only a few state handlers, hide the field, make the field read only, or leave the field alone. The dialog to allow the rules to be configured is most of the work. And yet, they are surprisingly difficult to explain in documentation. I’ve done it several times in several different ways and ended up with several different sets of misunderstandings. I’ve come to think that it is so because I usually start right off trying to satisfy realistic requirements, which usually requires multiple rules for a single field, without first explaining the kind of things you can configure in an individual rule in a vacuum. So I mix in the concepts of individual rules and rule collections, it all runs together a bit, and there are usually too many ambiguities in my description.

I find the best way is as follows:

  1. Explain the kind of rules that can be configured based on the type of condition, more or less in a vacuum, and don’t worry if the rule by itself doesn’t seem that useful.
  2. Explain a few rules with multiple conditions.
  3. Explain how rules are matched and executed and when processing stops for a given field, when there are multiple rules for a given field (i.e. precedence of operations).
  4. Provide step by step instructions for creating a few rules on a given field, and then explain the result of creating those fields in the form (i.e. reinforce precedence of operations).
  5. Throw in a few more complex examples. This is where we’ll get back to our scenario.

So that’s what we’re going to do. But first, here are the step by step instructions to start configuring a field visibility rule for a given field, because I really don’t want to provide these same steps over and over in the examples to come:

  • On the properties pane, find the field you want to create a rule for and click on the little key icon button to the right of the field. This brings up the Conditional Visibility Dialog for the field:

  • Now click on the + icon button. This brings up the Add/Edit Visibility Rule Dialog.

3.1 Simple Rules

For a new rule, the Add/Edit Visibility Dialog comes up looking like this:

image

There is a lot of stuff here, most of which we're going to ignore for a moment. The only required field on this dialog is the State, which determines what you want done to the field if this rule is executed. Choose Hidden as the State and click the OK button. The Conditional Visibility Dialog now looks like this:

This rules just says hide the field from everyone on all forms with no conditions. As a stand alone rule, this is rarely going to make sense, if you never want it displayed or editable, why did you add the field in the first place. I suppose you could be setting the field through a workflow and using it in a view or something like that. However, once we start looking at multiple rules and precedence, you may find that you are writing rules like this pretty frequently as part of a set of rules for the same field, but we'll get to that in a bit.

Looking back at the Add/Edit Rule Dialog you can see the forms to which the rule applies, and New, Edit, and Display are all checked by default. Click the gear icon next to the rule to edit it, remove the check on the Edit and Display, click OK. Now the rule says hide the field on the new form with no other conditions. This rule is more likely to make sense even as a stand alone rule. It satisfies all of the 'the address field should be on the edit form but not the new form' type requirements, and I've certainly been given real requirements like this before. If you click the OK button on the Visibility Rules Dialog and the Save button on the ribbon, you can go to the new Contact form and the Full Name column is now gone. If you save a Contact and go to the edit form, it's back. That's about it for the simplest of rules.

3.2 Rules Based on SharePoint Group Membership (and Author)

The next class of requirements that I wanted to satisfy is the 'some people should see it, others should not' type of requirements, which is the most common use case for conditional visibility. To accomplish this, you need to put the people in question in SharePoint groups and then create a rule using those groups, like so:

The applies to control is an entity editor, much like SharePoint's people picker, which mostly works but I know still needs some work too. It allows you to start entering a SharePoint group name, provides auto complete on contains case insensitive, and when you select a group it adds an entity. To remove an entity click the X on the entity. Where it falls short is that if you type some text but don't resolve it to an entity, when you click OK it silently throws away your text instead of raising a validation error, even if you typed the full group name. I may fix that before the first release, I may not, but either way I know it is a little weak and will fix it eventually, and for now I've warned you about it so caveat emptor.

Back on point, the above rule says hide the field for members and visitors with no other conditions. This will show the field to anybody not in those groups, so it satisfies some of this type of requirement. For more complex cases, you need multiple rules, and blah, blah, blah, we'll get to it soon I promise.

The other thing to note is the author check box in the applies to area. This is there to allow you to apply a rule specifically to the original author of the item (i.e. whoever opened the new form and saved it). It's not that uncommon to get requirements like make this field editable by the author but read only for everybody else, and without this check box there would be no way to generally satisfy this requirement. Of course, once again you'd need multiple blah, blah, blah, because a single rule can only have one state.

Finally, I've done this kind of solution before and I'm guessing when and if I get feedback, one common request will be to add support for configuring rules based on Active Directory users and groups. Just to be clear up front, I will NEVER accept this requirement. OK, let me back up a bit and say I will consider accepting this requirement if you can give me a compelling reason why it is needed, but I'm going to be the sole arbiter of what is compelling and I will bet you can't. The rest of this section is going to be a bit of a rant on why, and it's kind of a historical sequence of events, so if you don't care you can safely move on to the next section of this document:

  • In the past I have allowed rules based on SharePoint groups, AD groups, and even individuals.
  • I generally document that I recommend using SharePoint groups only and why.
  • Every single person that I know of who actually uses my feature configures lots of complex rules based on AD entities only, in most cases individuals but a few somewhat enlightened souls at least use AD groups.
  • People come and go from organizations, and for that matter organizations come and go, get renamed, split and merge, etc., which of course results in AD groups coming and going.

I think you can probably see where I'm going with this, right? This all leads to another sequence of events:

  • People start asking for enhancements like an interface to change all the rules for entity X to now be for entity Y, to which I politely reply no thank you (people who have worked with me in the past will refute this characterization of my response) and explain that this is precisely the reason I recommended using only SharePoint groups. On the bright side, they already have an interface I explain. The configuration is all JSON, open it in an editor, ctrl+H, search and replace. But do remember that earlier I said muck with the JSON manually AT YOUR OWN RISK.
  • The bug reports start coming in. The form crashes. Tiger teams are formed, debugging begins, and it turns out the form doesn't like it very much when there are rules based on a person or group that no longer exists in AD (or is disabled, or had their name changed, or is a group in a protected OU that the current user doesn't have access to etc. etc. ...). Of course in a perfect world all of these problems would have been shaken out in test, but it's hard to adequately test all the edge cases when you are doing the work at an organization at which you do not have AD admin privileges.

So anyway, my case is simple; that you should always use groups for this kind of configuration, and that the administration of these groups should be within your control. Most SCAs are not AD administrators. Q.E.D.

3.3 Rules Based on the Value of Another Field

The last class of individual conditional requirements I wanted to satisfy is rules like 'make the field hidden if Code is red, read only if Code is green, and editable if Code is blue. This will obviously require multiple rules and we're still not ready for that, but the basic building block for this type of rule is something like:

Which is make the field hidden when Code equals red. Note that all three of the comparison operators built in are case insensitive. I went back and forth on this a little, but mostly I question the usefulness of having a form where red and Red are both options but mean different things, so I think I settled on the most common use case. In addition to Equals, the built in comparison operators include Matches and NotMatches. If the value is literal, then these are equivalent to Contains or NotContains. But Matches and NotMatches also accept and will evaluate JavaScript style regular expressions. If you're not familiar with regular expressions, start binging because this document is not going to attempt to explain them, but a really verbose/obtuse way to achieve the equivalent of what's above would be

"And When Code Matches ^[Rr][Ee][Dd]$"

(unnecessarily verbose in this case because the comparison is already case insensitive, but if you know anything about regular expressions you get the idea). It's also important to understand what you are comparing too. You're comparison is against the text that is displayed when the field is read only (or more accurately, the HTML). It is not against the internal representation of the data as it is stored in SharePoint. So don't try matching a user with something like "2;#Joe McShea", that's not going to work. What's displayed for a user is a link to the userdisp.aspx page with the text of the display name, so that is what you're comparing against. If you are not sure what to look for, make the field read only for everyone, open the edit form for an item that has a value in the field, and look at the source in the DOM inspector or debugger of your browser.

One of the cool things about rules based on the value of another field is that they will be executed immediately as the value of the other field changes on the form. So save the above rule, open the new Contact form, and change the Code to Red and the Full Name field should disappear. Change it back to Green and it reappears. But in the interest of full disclosure I should note that I started off this paragraph with a half truth. This only works for some types of 'other fields' right now. I've tested it on check boxes, radio buttons, drop downs, multi-select choices, and even single and multi-line text fields and it works. But I also know it doesn't work on rich text, enhanced rich text, and date fields, and I haven't even bothered to test some field types. I suspect where it doesn't work it is because Microsoft has their own change listeners on the controls and they are swallowing the event, or something like that, but I haven't looked too hard to prove that at this point. What it comes down to is, I satisfied most of the requirements for this type of functionality that I've encountered in the real world just making this work with choice fields, so I've moved on for now.

The final thing of interest for this type of rule as a stand alone rule is that you can have more than one condition in a rule. Up to 3 right now just to simplify the UI, but the back end supports an unlimited number and I may make the UI more flexible later on. You add conditions by clicking the + icon button, and multiple conditions in a rule are ANDed together, so:

says when Code Equals red AND State/Province matches VA. You can do OR as well, but only with multiple rules, and blah, blah, blah, if I'm sick of saying it I imagine you're sick of hearing it.

3.4 Rules that Combine the Concepts Described Previously

So there are basically three fundamental types of conditions as described in the three previous sections, Applies To, Forms, and And When. You can specify any combination of these conditions in a single rule. When more than one of these types of conditions is specified, they are ANDed together. And I've already said it in the previous sections, but it bears repeating succinctly and in one place to avoid confusion; each of these types of conditions can contain multiple comparisons, and when they do, weather it is an AND or OR is handled differently for each, so to reiterate:

  • Applies To: specify Author and one or more groups, or multiple groups, and it is an OR comparison, i.e. 'member OR visitor'.
  • Forms: specify more than than one form and it is an OR comparison, and if this isn't intuitive to you, how in the heck do you imagine somebody could be on the New AND Edit forms at the same time.
  • And When: specify more than one condition and it's an AND comparison, i.e. 'Code Equals red AND State/Province Equals VA'. You can achieve OR with these conditions only through multiple rules, which thank heaven we're finally ready to talk about.

3.5 Multiple Rules for a Field and Precedence

Consider the following rules for the Full Name field:

image

How do you imagine these rules will be interpreted. Hint: not as they were intended to be interpreted I'm guessing. Rules are evaluated as follows:

  • Rules are evaluated in the same order in which the appear in the UI.
  • If a rule is evaluated to be true, it’s state handler is executed.
  • Once a state handler has been executed, all rule processing for the current field is terminated until another event occurs which starts the rule evaluation processing at the beginning.

So when the above rules are evaluated, the first rule, which applies to everyone with no other conditions is always true, the field is always hidden, and the other rules are never evaluated. To get the intended results, you need to reorder these rules like so (which you can do via drag and drop):

image

That’s better, but understand that these rules must be in this order exactly to be interpreted consistently. You may think that you can reverse the first two rules and the results are the same, but these rules are not mutually exclusive. Somebody can be both the author and a member, or a member and a manager, and if you reversed the order of the first two fields these users would always see the field as read only, which is clearly not the desired result but given the precedence of operations it is what you told SPEasyForms you wanted.

The other thing to note with this set of rules is the state of Editable. This really just means don't do anything to the field (so for instance on the view form it will still be read only). Why would we need such a rule? I can easily accomplish nothing without any rules whatsoever; heck, without any code whatsoever too. In this case it is so I don't fall through to the 'hide the field from everyone' rule. This is the reason why ‘hide the field from everyone’ may make sense as part of a set of rules even though it usually does not make sense as a stand alone rule. It's kind of like firewall rules if you are familiar with the concept. You need to put specific rules before general rules, so in order to satisfy requirements like ‘managers can edit, but for everyone else it should be hidden,’ you need some way to specify a rule that permits managers to edit, even though allowing edit is the default if there are no rules whatsoever.

3.6 Putting it all Together (and back to the scenario)

For our scenario, we have the following requirements for the given fields:

  • Company, Content Type, Full Name, and Job Title
    • should be hidden when Code equals red.
    • should be read only when Code equals green.
    • should be editable when Code equals blue.
    • should be editable by Manager at all times.
  • All fields on the HR tab or content area (i.e. EmployeeId, HireDate, EmergencyContact, and HomeAddress)
    • should be editable for people in the HR group.
    • should be read only for people in the Manager group.
    • should be hidden from everyone else.

Lets take the first set of requirements and start with the Job Title field. First off, given what we now know about precedence of operations, these requirements are not in the order in which they should be implemented, but customers do not really care about such technical details. The configuration for Job Title should look something like:

In this case something like is accurate, because since the last three rules are mutually exclusive it does not matter what order they are in, the code will never be both red and green. If code were a multiple choice select field it would be a different story. But the manager rule has to be at the top, or one of the other three rules will always get executed before it is reached. Note also, that the rule that says 'make Job Title Editable if Code equals blue' is completely unnecessary. If removed, when Code is blue and the current user is not a manager, it will drop through all rules without executing any of them, and the result is the same. I think it is a little cleaner with the unneeded rule, but you can decide for yourself. If you configure the above rules for all four of the fields named above, the Conditional Visibility View will look like:

image

This view is the only place where you can go and see all of the visibility rules for the form (for a given content type, rules that are for fields that do not exist in the current content type are hidden). The rules are sorted by column display name. There are no buttons, and you cannot drag and drop these rules from here, but you can double click on a rule to bring up the Conditional Visibility Dialog for the given field.

Once you have saved these rules you can check out how they affect the form, but before you do, make sure you know if you are in the Manager group or not, or you may once again be utterly unimpressed with the lack of anything new happening in the form (I’ve made this mistake before a few times, generally ending in a humbling debugging exercise). By the way, if you add or remove yourself from the Manager group, you should just have to refresh the form to see the difference. The current user’s group membership is not cached in any way across page loads, so the effects should be immediate.

Lets move on to the second set of requirements, starting with the field EmployeeId. The configuration for this field should look like:

image

Note that I didn’t say something like this time, the order of these rules is entirely significant. The last rule obviously must be last because it always executes. But you also cannot reverse the order of the first two rules, because if you did then somebody in both the Manager and HR groups would see the field read only while somebody in just the HR group would see it editable, which I doubt is what you want. Go ahead and configure the other three fields like this and the Configuration Visibility View should now look like this:

image

Save the configuration, go to the new Employee form, and check out the results. You should now know pretty much everything you need to know about conditional visibility rules. Try adding some of your own. Refresh the form and check out the result.

3.7 Validation

Note that if you use conditional visibility to hide a field or make it read only, and the field has validation errors, the user will be unable to submit the form. The OOB validation message is hidden, because the entire cell is hidden. If the field is on a tab or accordion content area, the header will be highlighted in red and the first one with validation errors will be automatically selected, but again the OOB validation message is hidden. Even if the validation message was displayed, the user would not be able to fix the problem because there are no input controls in which the required field can be entered. So as a general rule of thumb:

  • Do not hide required fields or fields with validation from users who have contribute access to your list.
  • If you must hide a field that potentially could have validation errors, make sure that it always has a default value that will pass validation.

4. Field Control Adapters

Field Control Adapters are basically intended to be a replacement for custom fields in SharePoint, or at least to provide custom field like behavior in SharePoint forms using only OOB field types. There are numerous shortcomings of custom field types. For starters they are a farm solution, which is tantamount to being downright evil by modern Microsoft doctrine. But they also suffer some reduced functionality, for instance they cannot be edited in datasheet view. This has always struck me as an unnecessary limitation; why not let people edit it just like an SPFieldText if it is based on SPFieldText, but Microsoft chose to punt and it is what it is.

This is also the area where I see SPEasyForms expanding the most in future releases. The possibilities are nearly endless. Have you ever gotten requirements like:

  • I want this field to be an integer, but the control should be a thermometer with a slider.
  • I want this field to be a voting/star system where the user casts their vote by moving a dogs tail up or down.

These may be obscure cases, but if you can imagine it, you can probably find someone out there who will say ‘yeah, give me one of those.’

But for version 1 of SPEasyForms I’ve tried to implement just a couple of these that I consider to be low hanging fruit, meaning I’ve been asked for these often or I’ve seen people asking how to implement these in a SharePoint list often. The two I’ve implemented, in perceived order of popularity, are:

  • Cascading Look Ups – the ability to trim the options available in one look up field based on the value selected in another look up field.
  • Autocomplete – the ability to provide type ahead functionality for a text field based on the values in a field on a different list in the SharePoint site.

I will document these in the reverse order below, just because Autocomplete is the easiest to setup, but before I do I want to document the steps for getting to a control adapter dialog for a given field right now so I don’t have to repeat it in the implementation specific sections below:

  • Hit the shuffle icon button (looks like 2 intertwined arrows) next to a field in the properties pane. Note that if this icon does not appear next to a particular field, it is because there are no adapters currently available for that field type.
  • If there are multiple adapters available for a given field type, you will be prompted to choose which implementation you want applied to this field:

image

  • Once you choose the implementation, an implementation specific adapter dialog will be opened to let you configure the adapter. Note that if there is only one implementation for the given field type, the dialog above is skipped and you jump right to the implementation specific adapter dialog.

The adapter specific dialogs will be described below, but one thing I should point out first is that if you have just installed SPEasyForms with no plugins and no custom code of your own, you will never see the above dialog. That’s because there are only two adapters built into the product, one for SPFieldText and one for SPFieldLookup, so there is no way you are ever going to choose a field that has two potential implementations. The above dialog was baked into the product just to allow for the possibility of plugins.

The second general point I want to make is that even if there were multiple adapter implementations available for a given field type, you will only ever be able to configure a specific field to use one adapter or the other. To change the adapter for a given field, you must first remove the adapter and then add one again choosing a different implementation. How you remove an adapter is entirely up to the adapter specific dialog. The reason you will only ever be able to put one adapter on a specific field is that adapters manipulate the DOM of the OOB controls for a field, and would almost certainly step on each other. Not buying it? Try to imagine merging the functionality of the dog’s tail voter and the thermometer slider described at the beginning of this section in any kind of generic way. Think about it?

4.1 Autocomplete

In order for Autocomplete to be configured, all you need to know is the name of another list in the same site and the display name of the field in that list that you want used for type ahead functionality. For our scenario, my requirement is going to be:

  • The Job Title field should have type ahead functionality based on the values of the title field in the JobTitles list.

I’ve already created the JobTitles list and populated it, and it looks like this:

image

So when I click on the shuffle icon button next to Job Title I am presented with the following dialog:

image

Of course yours is not all filled in yet like mine is, I just didn’t want to do before and after screen shots. The only configuration is that you need to select the title of the lookup list and the title of the lookup column. The screen may freeze for a few seconds when you first launch this dialog or when you choose a lookup list. The first case is because I need to get a list of list titles for the site from a web service, and the second is because I need to get list meta data from a web service. In both cases I cache the result so subsequent usage of the same data in the same browser session will be faster.

Anyway, once I’ve configured this and saved my configuration, I can go back to the form and I should have Autocomplete functionality on the Job Title field:

image

And that’s all you need to know about Autocomplete…sort of. You didn’t think there wouldn’t be another caveat, did you? If you look back at the screen shot of the JobTitles list, you can see that there is a count in the view, and the view currently has 2499 items in it. If the view has more than the list view threshold for SharePoint (usually 5000 items) you may run into some pretty insurmountable performance issues, especially in Internet Explorer. In fact, sometimes the browser hangs with 4000 items. It may be worse if you are bandwidth or latency challenged or your SharePoint farm is not very speedy.

This is in part because of the current implementation of the Autocomplete adapter, which fetches the entire list into a big array on form load (well, just the one field, but still it can be a non-trivial amount of data). I could theoretically make some performance gains by not fetching the list until the user typed a few characters and trimming the results on the server side by sending a CAML query. On the other hand, that would mean more web service calls if the user changed the first few characters, which could perform even worse. I may look at a solution for larger lists in the future, but for now I think I’ve satisfied the low hanging fruit of Autocomplete.

If you want to remove an Autocomplete adapter from a field, open the dialog, blank out the lookup list control, and hit Ok.

4.2 Cascading Look Ups

Do a search on Bing for ‘sharepoint cascading lookup’ or ‘sharepoint cascading dropdown’ and you’ll see a lot of questions and even a lot of solutions. I chose not to write my own since there is a perfectly good implementation in SPServices, which I’m already using for calling all of the SharePoint web services, so if you have ever used cascading lookups using SPServices you already know how to setup the lookup lists. If not, I’ll show you in a moment, but first lets talk about the requirements for our scenario:

  • The options in the SalesDivision drop down should be trimmed based on the value selected in the SalesRegion drop down.
  • The options in the SalesState drop down should be trimmed based on the value selected in the SalesDivision drop down.

Pretty standard stuff in terms of cascading lookup requirements. The lookup lists look like:

image

image

image

The concept of cascading lookups depends heavily on a relationship list, which describes the relationship between a parent column and a child column. In the case of the first requirement above:

  • The parent column is SalesRegion and the child column is SalesDivision.
  • SalesDivision is also the name of the relationship list.

There is a parent field and a child field in both the relationship list and the current form, and that is what you need to pair up to configure cascading drop downs. The relationship list is a lookup list for the child column in the current form. It also has a lookup to the list that the parent column in the current form looks up against. When I say the current form, I’m talking about the form you are currently configuring in SPEasyForms.

Note that in my case I have also modified the fields in my lookup list so the display names of the parent column and child column match the display names of the lookup fields in the current list. This is not strictly speaking necessary, but it does make the configuration of cascading drop downs much easier as I’ll demonstrate in a moment. I’ve also grouped the views above by the parent lookup field, which isn’t necessary at all to make this work, but doesn't it look nice?

To configure cascading drop downs, click the shuffle icon button next to the child lookup field (the one that will be trimmed) in the properties pane (for requirement 1 that’s the SalesDivision field). That brings up the Cascading Lookup Dialog:

image

It may take a couple of seconds to launch if I haven’t already cached the list of list titles. The only things filled out on load are the name of this list and the name of the child column. In order to configure the rest, I first need to select the name of the relationship list, which in this case is SalesDivision, after which the dialog looks like this:

image

And voila, we’re done. I was able to guess the rest of the configuration because there is only one lookup in the relationship list and the display names in the relationship list match the display names in the child form. If that were not true, I would have had to manually marry up the relationship list fields with the current form fields. So follow the same steps to configure the SalesState cascading look up, and the form fields now look like:

image

Note that there are no options to select for SalesDivision or SalesState. Select a SalesRegion, and SalesDivision gets appropriate options:

image

And if you configured SalesState correctly, select a SalesDivision and SalesState should have appropriate options.

If you want to remove a Cascading Look Up adapter from a field, open the dialog, blank out the relationship list control, and hit Ok.

And that is all you need to know about cascading look ups. No really, no caveat.

4.3 The Field Adapters View

Just as there is a view for seeing all visibility rules, there is also a Field Adapters View in the editor for seeing all configured adapters by field display name (for the current content type). After configuring the adapters described in the previous sections, this view should look like this:

image

The last column in this table shows adapter specific configuration in the raw, because the editor does not know anything about this configuration information other than that it is in the configuration. Also note that the foreign lists are stored as GUIDs. This means that if this configuration is exported and imported into a list in a different site, the adapters will need to be reconfigured. I may try to fix that or at least provide an easy way to reconfigure them prior to the first release, if I get a chance.

4.4 Validation

Neither of the two adapters included in the first release has any validation issues, since they do not hide the field/controls, they just augment the functionality of the field.  It is certainly quite possible that a field adapter could hide validation errors from the user, making it difficult or impossible for the user to submit the form, but validation works the same on Autocomplete fields and Cascading Look Up fields as it does on OOB text fields and look up fields.

5. Wrap Up

Well, that’s it. I think I’ve now described all of the functionality that will be included in the first release. This document has gotten a lot bigger than I thought it would. But then, there are a lot of pictures, which is kind of required if you want to describe a user interface. Before the first stable release, one of my remaining tasks is to turn this document into a modern, menu driven help system, and add some context sensitive help to the user interface (at least rudimentary context sensitivity, for instance if you are on the adapter view, take you to the adapter help).

When I set out on this project, my goal was to provide a turn key professional solution that could be installed and used by administrators and power users. I think I’ve achieved that goal somewhat. Agree or disagree, I’d love to hear your feedback on the SPEasyForms CodePlex site. I also wanted to make it extensible with a plugin architecture. I think I’ve achieved that to some degree too, and I will start documenting it as soon as I’ve done the first stable release.

The nice thing about the requirements in the scenario used in this document is that they all mapped perfectly to what SPEasyForms already does. You’re mileage may vary.

Last edited Nov 11, 2014 at 3:04 PM by mcsheaj, version 6