Sunday, February 13, 2011

How to Customize the SharePoint List "NewForm" using VS2010 instead of SharePoint Designer

Most blogs show you how to customize the NewForm of a SharePoint List by using SharePoint Designer. However when you need to support/maintain a SharePoint Solution you really should use a Solution (.wsp). Easiest way is to use VS2010. In this blog I demonstrate how to create a customized NewForm, this means. When a user clicks 'New Item' in the list it will render a customized version of the 'New Form'. It's possible to add additional Web Parts and content. In this version it will however still use the default ListFormWebPart to render the new-item form.
I assume you already have created custom Fields (Site Columns) and Content Types in VS2010.
The steps to take are:
  1. Create ListDefinition
  2. (optional) Create ListInstance
  3. Create a custom page that will hold the customizations
  4. Customize ListDefinition schema
  5. Deploy the solution, activate feature
Step 1: Create ListDefinition
In VS2010, you have a choice to create a new ListDefinition based on Content Type and just a plain ListDefinition. In this demo I chose the latter.

I want to create a List Definition based on Custom list. I also create to create a List Instance (Step 2) so after deployment I immediately have a custom list created.

Step 3: Create a customized NewForm
In schema.xml of the ListDefinition you see this line:
<Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
The SetupPath point to the 14-hive\templates folder. So In this case it will provision a NewForm.aspx based on the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\Pages\form.aspx
You don't want to change this out-of-the-box page. It will void you support from Microsoft ;-).
So make a copy, copy it into the ListDefinition project and rename it to MyNewForm.aspx. Make sure you include MyNewForm.aspx into the VS2010 project and set the 'Deployment Type' to ElementFile, this will deployed the file to the feature directory. It should now look like this in VS2010.

Add some content to the NewForm:
Open the MyNewForm.aspx and look for the PlaceHolderMain ContentPlaceHolder (Line 244).
Put some content like <h1>Hello Customized World</h1> in front of the the <table …> a few line below.
Add a Web Part Zone to the NewForm:
Add: <WebPartPages:WebPartZone runat="server" FrameType="None" ID="Top" Title="loc:Top" /> after the <h1>Hello…

So it will look like this:
<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
<SharePoint:UIVersionedContent UIVersion="4" runat="server">
    <ContentTemplate>
    <div style="padding-left:5px">
    </ContentTemplate>
</SharePoint:UIVersionedContent>
    <h1>Hello Customized World</h1>
    <WebPartPages:WebPartZone runat="server" FrameType="None" ID="Top" Title="loc:Top" />
    <table cellpadding="0" cellspacing="0" id="onetIDListForm" style="width:100%">
     <tr>
      <td>
     <WebPartPages:WebPartZone runat="server" FrameType="None" ID="Main" Title="loc:Main" />

Save the changes ;-).
Step 4 Change the Schema.xml
Now we have created a custom page, however we need to tell the ListDefinition to use the customize NewForm. To do this, we need to change the Form element in the ListDefinition schema.xml
Code Before:

<Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />


Code After:
<Form Type="NewForm" Url="NewForm.aspx" Path="MyNewForm.aspx" WebPartZoneID="Main" Default="TRUE" UseDefaultListFormWebPart="False" WebPartOrder="1">
  <WebParts>
    <AllUsersWebPart WebPartZoneID="Main" WebPartOrder="1">
      <![CDATA[
    <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2">
      <Assembly>Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>                         
      <TypeName>Microsoft.SharePoint.WebPartPages.ListFormWebPart</TypeName>
      <PageType>PAGE_NEWFORM</PageType>
    </WebPart>]]>
    </AllUsersWebPart>
    <AllUsersWebPart WebPartZoneID="Top" WebPartOrder="1">
      <![CDATA[
    <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2" xmlns:iwp="http://schemas.microsoft.com/WebPart/v2/Image">
      <Assembly>Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
      <TypeName>Microsoft.SharePoint.WebPartPages.ImageWebPart</TypeName>
      <FrameType>None</FrameType>
      <Title>My Custom Image</Title>
      <iwp:ImageLink>/_layouts/images/homepage.gif</iwp:ImageLink>
      <iwp:AlternativeText>Logo</iwp:AlternativeText>
    </WebPart>]]>
    </AllUsersWebPart>
  </WebParts>
</Form>

What I've done is:
  • instead of using the default /pages/form.aspx, I told it to use the MyNewForm.aspx (So I changed SetupPath="pages/form.aspx" to Path="MyNewForm.aspx", it should not look into the template directory but in the feature directory, so SetupPath => Path…). The file will still be accessible with url NewForm.aspx. You can change that if you want.
  • UseDefaultListFormWebPart="False", it will not add a default ListFormWebPart, but it will process the <WebParts> child elements.
  • The <WebParts> child elements are used to place web part on the Custom MyNewForm.aspx
    • first web part is a ListFormWebPart. When setting the PageType to PAGE_NEWFORM, it will add a ListFormWebPart that will handle the 'New Item' rendering, make sure the WebPartZoneID matches with the ZoneID's in the customized form. Default there's a Main ZoneID.
    • second web part is a Image Web Part, showing a default MS SharePoint logo. This web part will be placed in the Top WebPartZoneID (our custom WebPartZone).
Final Step: Deploy solution and activate feature.
Deploy the solution using VS2010.
Visit the site where you deployed the solution. If VS2010 didn't automatically activated the feature, you should go to Site Settings, Manage Site Features and look for feature 'CustomListDemo Feature1' (This is why a naming convention is recommended ;-)). So make sure it's activated.
As the feature included a listinstance a list is created. The list name is: "CustomListDemo - ListInstance1".
Go to this list and click on 'New Item'.
This will be the result:

As you can see. The custom NewForm, including some custom content, a custom Web Part and the default ListFormWebPart. This is just a simple example. But you could go wild on the content and on adding your own Web Parts. It's also possible to change the template the ListFormWebPart uses. But that's for another day…

Read some more about Customizing Form.
You can follow me on twitter

10 comments:

  1. I cannot thank you enough. This has been a tremendous help to me. I look forward to your future posts.

    /A SharePoint Newbie

    ReplyDelete
  2. You are the man. This is exactly what I was looking for.

    Looking forward to future articles.

    cheers
    Paul

    ReplyDelete
  3. Best example I have found yet. Very clean and concise!!!

    ReplyDelete
  4. Thank you for this post: simple and efficient !

    ReplyDelete
  5. I like the post but step 4 has an issue; it doesn't accept the "WebParts" to be a child for the "form" and aa a result it requests me to close "Form" tag of the newform..
    Did i miss something?

    ReplyDelete
  6. Can you post the source code?

    ReplyDelete
  7. Has anyone tried this on SP 2013? UseDefaultListFormWebPart="FALSE" does not work, it throws error

    ReplyDelete
  8. The above steps did wonders for me...

    Thanks!!

    ReplyDelete
  9. Tanks but how can I customize the form?
    I need a CheckBox and DropDownList (I got DDL without value when I add column type = Choice)
    I don't have a MyNewForm.aspx.cs file.

    ReplyDelete
    Replies
    1. You cannot do it like that. You could add a ASP.NET control on the page. Make sure to add a reference at the top page. Place the control where you need it. Put the ASP.NET User Control file in the 14 hive Template\ControlTemplates\ directory. If you Google on user ControlTemplates in SharePoint you will find the solution.

      Delete

Note: Only a member of this blog may post a comment.