harePoint’s built-in tools are good at providing a basic interface for adding and editing data, however, there are times when the included editing features aren’t enough. There are applications where the SharePoint list will work, except for one small detail. For instance, you may need to ensure that one of the fields in your list matches a back-end data source. This might be accomplished by creating a drop-down that is populated from a back-end system, or perhaps it’s some custom validation that ensures that the data that the user enters is in the back-end system.
Tearing open SharePoint to find a facility for these additional features is difficult. It requires an understanding of how SharePoint works overall as well as how it handles drawing a list. However, by the end of this article you’ll understand the overall architecture, the details that make it work, and you’ll have a framework for creating your own custom list editing solution.
One Little, Two Little, Three Little Web Parts
You know that SharePoint is built on Web parts, however, the extent to which SharePoint utilizes Web Parts internally may surprise you. Nearly every page that you see in SharePoint—from the default.aspx on every site to the forms pages at the heart of each list—is a Web Part Page.
Although the list pages don’t look like it, they are Web part pages. They don’t have the controls to allow the user to edit the page, but they are Web part pages nonetheless. If you would like to prove that to yourself simply add ToolPaneView=2to the end of the query string and reload the page. You’ll see that the Add Web Parts tool pane, the border around the Main Web part zone, and the title bar on the default Web part will show up.
The Web part that SharePoint uses to display and edit items in a list is the same one used to add new items to a list—that is, the ListFormWebPart. With the trick of adding ToolPaneView=2 to the end of the URL you can add or remove Web parts from any Web part page in SharePoint. Figure 1 shows the result of adding ToolPaneView=2to the end of the query string on the edit page of an announcements list.
|Figure 1. Adding the ToolPane View: The Add Web Parts toolbar shows up if you add ToolPaneView=2 to the query string.|
Because you can add or remove Web parts from any page it becomes possible to swap out the SharePoint provided ListFormWebPart for your own Web part that performs a similar, but not identical, function. You can add to ListFormWebPart’s basic functionality by adding enhanced validation and/or access to a database for populating drop-down boxes.
There are a few limitations that you must be aware of if you decide to modify the editing in SharePoint. While this technique will allow you to change how users modify data while in the Web interface, it won’t stop them from editing the data in either data sheet view or in other applications via the SharePoint lists Web service. The most frequent example is the way that Excel spreadsheets remain linked to the data.
So while it’s possible to change the way users edit data from within the Web interface, the technique isn’t perfect. You’ll have to make sure that you either remove this functionality from the list template to edit in the data sheet view or educate your users on the limitations. Generally, educating users that the data sheet view remains true to the core SharePoint functionality is acceptable. They get the enhanced editing functionality only through the Web interface.
How the ListFormWebPart Works
The way that the ListFormWebPart works is fairly simple. It draws its header based on the properties of the list, it draws each user field, it draws the attachments, and it draws the footer. The process is very simple but also extremely powerful. The basic structure of the Web part is repeated for each of three modes in which the Web part can be drawn: display, edit, and add.
Because I’m only interested in creating new items and editing, I can leave the existing ListFormWebPart in place for displaying a list item. That will allow me to focus my efforts on the add and edit functionality. With a few thousand lines of code it is possible to replicate the add and edit functionality of the ListFormWebPart, as you’ll see in the rest of this article. Once you have replicated the basic functionality of the Web part it’s easy to add additional functionality like the ability to fetch from an external data source.
Creating the ListFormWebPart replacement
There are a few fundamental pieces of information that you need to make your replacement ListFormWebPart work. They are:
- What List is being worked on?—Obviously you need to know what list to display fields for.
- What list item is being worked on?—This not only tells you which item to display when editing but its absence tells you that you’re adding a new record.
First, the list being worked on can be extracted from the URL that the control is being called on if in a list, or it can be stored in a property of the Web part. Because you can drop the Web part on any page, the latter method is a great tool for testing. It also provides flexibility in how you construct your sites.
The list item comes from the query string. SharePoint provides the ID number of the list item in the query string.
The example code shows you a working prototype that supports the basic structure for a few of the fields. There are a few basic pieces: enhancedlistformwp.cs, form.cs, field.cs.
The EnhancedListFormWP code is the Web part code. It has the public properties, defines which list the Web part is supposed to be working on, and uses CreateChildControls to add the form to the output of the control. (See my earlier article, “Wrapping Web Controls in a SharePoint Web Part“).
Form.cs draws the header and sets up the output so that each field can be drawn one-by-one. The HTML emitted from form.csis designed to match the output of the ListFormWebPart. From the styles to the tables the output is nearly identical. This helps minimize the possibility that the user will notice the difference between your control and the built-in control.
The Form sets up the Web part so that it will post back via a FrontPage RPC (Save). This means that you don’t have to bother with the processing code to write the item back to a list. You can, however, change the code so that the post is returned to the Web part and the Web part processes the update to the list.
The workhorse of the sample is the Fields.cs, which does the work to draw each field. Fields represents a container for a collection of static methods that draw fields. The core is a dispatcher, ControlForField, which determines which type each field is and hands off the work of getting the right control to the individual field-focused functions. For instance, SingleLineField handles single-line text fields.
Adding it to the page
Once you have workable code (or have compiled the included sample application) and have installed it, you can add it to either the new or edit pages (newitem.aspx or edititem.aspx respectively.) To do this, add the ToolPaneView=2 on the query string on the page, browse to your Web part, and drag it on the page. Take the original Web part and close it. (Do not delete it since SharePoint wants to see that it still exists on the page.) Figure 2shows what the page looks like when you’re done closing the ListFormWebPart and have added the enhanced list form Web part.
You now have added the Web part to the appropriate page in the list. Now when you go to add or edit an item your Web part will be displayed rather than the SharePoint list form Web part. Figure 3shows the resulting page—it should look identical to the way the edit page looked before we started.
Enhancing the Edit Experience
Now that you have your own code for editing SharePoint lists it becomes a trivial task to support new fields or options. Here are a few ideas for how to support new features with your new enhanced editing form:
- Get a drop-down from a database—By using the description field for a SharePoint field you can store away the configuration necessary to connect to a database, retrieve values, and display them in a drop-down box.
- Call a Web service—Using the same principles of stuffing configuration into the description box you can setup a Web service that returns the data that you need.
- Validation—Another approach is to have your Web part read its operation from the web.config file and potentially even dynamically load DLLs to do multi-field validation. All you need to do is define an interface that turns over all of the fields to a type that implements an interface (say IFormValidate) and then use reflections to dynamically load and execute the specific code for the form.