Monday, October 24, 2011

A pattern for building custom forms in SharePoint 2010

Recently, I have been working on a pretty large enterprise intranet project on SharePoint 2010 that involves building a few modules that meet the business needs. These modules each involve a few related content types. The way we architected these was to have a main core content type for each module – and have a few other content types have a lookup column back to that core content type. There were some one-one relationships as well as one-many relationships in the mix. Given that there were these related entities, there is no OOB way to allow for a seamless experience for an end user to go through the entire process of creating the core entity and all related entities without needing to know how they are stored in custom lists. There were also event receivers that needed to be created in these modules that would do sub-tasks, set permissions on items, send email etc.
One of our key design goals from the onset was to make the user experience as friendly as possible while at the same time accounting for any changes/additions to fields to the content types after the project was delivered. So we did not want to build fully custom forms, because those would be tied strongly to the schema as we knew it during development and would need a UI change and deployment to add any new field to the custom pages
Here is an example of content types in one specific (relatively simple) module:

The approach we took was making extensive use of list field iterators in SP 2010. These are available in the SP API and are fairly easy to use once you get the hang of these. So these would allow us to point the ListFieldIterator to a list in SharePoint and set its mode to New, Edit or Display. What this would do is open up the list item in one of those modes. The iterator iterates through all the fields in that list and surfaces them to you, just like in an OOB SharePoint list form. If we needed to edit or display we would also bind the list item ID to the iterator and set the corresponding mode. If the user did not have permissions to edit the list item, we would show the iterator in the display mode.

Here is how the new/edit form looked with the iterators.

We used the Tab control in the AjaxControlToolkit to manage the UI using different iterators in the tabs. We also employed the modal framework quite extensively to manage sub types as shown below. Here is the management screen for audit tracking.

On clicking new audit tracking entry, the user would get this screen as show below. Notice the Tab control and how the result looks like an OOB list form. It is easy to bind the iterator to the list and the item and set its mode (New, Edit or Display). The buttons below are custom and thus the saving has to be done by you as well.

You can click the new Audit Finding link to create a new sub type. Here is that screen.

As you can see above, this really is a SharePoint modal dialog showing yet two more sub content types in their own lists and related to the main core Audit content type. The modal framework is really handy for doing these sort of things and improving the user experience vastly. Imagine if the user had to go to 5-6 different lists to create a new audit, to say that would not fly would be an understatement!

Here is some code that highlights how to bind these. Here is the code to declare the iterator.

In the code behind, this is how you bind it.

SPList AuditTrackingList = SPContext.Current.Web.Lists[Constants.AUDIT_CORE_LIST_NAME];
ListFieldIteratorAuditTracking.ListId = AuditTrackingList.ID;
//Set the mode as well depending on whether you are opening an existing one to display or new one. lets go with new for here
ListFieldIteratorAuditTracking.ControlMode = SPControlMode.New;
//Could also be SPControlMode.Edit or SPControlMode.Display

Voila, your iterator binds to the list item and shows it just like SharePoint would.

To update/save, in your Button_Save event (obviously this is oversimplified):

 protected void ButtonSave_Click(object sender, EventArgs e)
            if (this.Page.IsValid)

                 SPItem item = ListFieldIteratorAuditTracking.Item;




eSignature said...

Very informative post. I sometimes do presentations on SharePoint and was wondering if I could use your Print List example in my presentations and refer my audience to your website for further info.

Rokki Winchester said...

It is good article you share for reading.