Sunday, June 26, 2011

SharePoint 2010: Approve/Reject dialog customization, show changed values

SharePoint provide rich support for approval process. You can maintain version of changes, you can use built-in workflows or develop your own for approval process. You can even create custom workflow activities and use it in SharePoint Designer to create your own approval workflow. Unfortunately, SharePoint doesn’t provide a nice UI where approver can get a snapshot of what’s changes he’s going to approve/reject. What we are familiar with the following UI:

image

Figure 1: Very generic UI to approve/reject

 

What if we could have a dialog as shown below:

image

Figure 2: Custom Approve/Reject dialog with modification highlighted

As shown in figure 2, the approver will have the better look of what’s the changes he’ll approve/reject. As shown in figure 2, the person who will approve/reject, can get a snapshot of what changes are waiting for his/her approval.

 

What’s the cost of custom approve/reject dialog?

Now the question comes what’s the development cost of such a custom approve/reject dialog? I’ve just developed few classes for returning a list of items with three fields (Field Name, Old Value and new Value) which can be bound to a grid. I’ve already provide the source code in here. But the development process is described below:

Create a custom action menu: You can hide the custom approve/reject menu or you can keep it in place. What I’ve done is included a new custom action menu ‘Approve/Reject Single’ as shown in the image below.

image

Figure 3: Custom action menu (Approve/Reject Single)

 

Create custom Application Page: Next you need to develop a custom application page which will be shown in the dialog when the custom action menu (show in figure 3) will be clicked. The custom application page will show the changes (field name, old value and new value) as shown in figure 2.

Download and test the code

If you have downloaded my last code from blog “Approve/Reject Multiple Items” please uninstall the solution first. Either you may find conflict as I’ve used the source code from that post and modified for this post. You can download the code for this post from my MSDN code gallery http://archive.msdn.microsoft.com/SP2010ApproRejectExt. Then from download tab download the second file “SharePoint.ApproveRejectTestWithVisual”.

Conclusion

The provided code is not something that you can just download and deploy in production. The code is just for can-do sample which shows such a nice view of changed items possible.

Wednesday, June 15, 2011

SharePoint 2010: Customize SharePoint Add/Edit/Display Form

When you create a SharePoint list the default SharePoint add/edit/display form get its looks by its own. For example the fields appears in the add/edit/display form based on the sequence you added the fields. Also by default all fields of the list are shown in the forms. Sometimes you may need to give a hand to customized that look and feel. I’ll try to give some light on how you can customize the default add/edit/view form of SharePoint list.

 

Enable Content type Management First

To customize the List forms you need to enable ‘content type management’. You can do so from List settings Page and then click ‘Advance Settings’. Then select yes for “Allow management of content types” as shown below:

image

Figure 1: Enable content type management.

 

Once you have enabled the content type for a list you will find a available content types associated with the lists under ‘content types’ section of list settings page as shown below:

image

Figure 2: Content type management section in list settings page

 

Hide fields from add/edit/display form

Sometimes you may want to hide some fields from add/edit/display form. Scenario might be you don’t want users to edit the field directly, rather the hidden field’s data will be populated differently (maybe from event receiver or timer job). To do so click on the Content Type (usually Item) and then you will be landed in a page as shown below:

image

Figure 3: Item Content Type editing page

 

As you see from figure 3, the content type page is showing all my field but only Product Name (internally the field name is Title) is coming from Item content type. Other fields are added by myself. Now let’s say you want to hide the launchDate field from add/edit/view form. To do so click the field link ‘Launch Date’ and you will be taken to a page as shown below. From that page you can hide a field.

image

Figure 4: Hide fields if needed

 

For your information, the hidden field will not appear in add/edit/display from but you can still access the field in list views.

 

Reorder Fields in add/edit/display form

You can reorder how the fields will appear in the list add/edit/display from. To do so take a look a the figure 3. You will find a link “Column Reorder” at the bottom of the item. Click the link and you will be moved to a page as shown below where you can reorder the presence of the fields in add/edit/display form.

image

Figure 5: Reorder fields in add/edit/view forms

 

Want more customization?

If you are not even happy you can create your own custom add/edit/display from as described my another post. Also you can even edit the add/edit/display from in infopath. To do so open the site in IE browser and the navigate to list settings page. And then click “Form Settings” as shown below:

image

Figure 6: From settings option in list settings page.

 

Clicking on the form settings page, you will be navigated to a page as shown below:

image

Figure 7: Form settings page.

 

Clicking ok in the page as shown in figure 7, you will be asked to open the page in InfoPath editor as shown below. However you need to use IE browser to open the InfoPath editor directly from browser:

image

Figure 8: Edit form in InfoPath.

 

I’m not going to bring InfoPath in today’s discussion as this can be more complex. However If I get chance I’ll come back to you with a post on “how to use InfoPath to edit the form”.

Tuesday, June 14, 2011

SharePoint: Custom add/edit/display form for list

Sometimes we don’t want to use SharePoint’s custom add/edit/display form. We want our own custom form when user will try to view, edit or add an item. I’ll show you today how easily we can do so.
For this post I’ll consider I’ll have a list with three fields: Product Code, ProductName and ProductDescription. I’ll show how we can create a list with these two fields with custom add/edit/display form. The list’s fields are described in the table below:
Field name Field Type Comments
Product Code Text Title field will be used instead of creating a new one
Produce Name Text
Product Description Text
Table 1: Custom list template/Content Type’s fields

The first step of this approach is to create a content type with required fields associated with the content type. The noticeable point here is that In the content type declaration, we can define custom forms for add/edit/display.

Step 1: Create a content type for your list

To create content type right click on your project and click ‘add new item’ and then select content type as shown below:
image
Figure 1: Add content type

Next you will be prompted for the base content type as shown below: If you want to create a custom list, you can select Item as shown below:
image
Figure 2: ‘Item’ is the base content type for custom/generic list

Then you will have provided the content xml file. You need to modify the content type xml file as shown below. Please modify the Inherits=”False” from the content types.
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <!--Defined fields-->
  <Field ID="{30C3D21A-A7C9-410E-A896-82875475F697}" Name="ProductName"
         DisplayName="Product Name" Type="Text" Required="FALSE" >
  </Field>
  <Field ID="{9621763e-3494-4a86-a3eb-fd2593f1a1f1}" Name="ProductDescription"
         DisplayName="Product Description" Type="Text" >
  </Field>
  <!-- Parent ContentType: Item (0x01) -->
  <ContentType ID="0x0100c5e54b7f62ad451a92f9235d43ec9082"
               Name="ProductContentType"
               Group="Custom Content Types"
               Description="My Content Type"
               Inherits="false"
               Version="0">
    <FieldRefs>
      <FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" 
                DisplayName="Product Code" Sealed="TRUE"/>
      <FieldRef ID="{82642ec8-ef9b-478f-acf9-31f7d45fbc31}" Name="LinkTitle" 
                DisplayName="Product Code" Sealed="TRUE"/>
      <FieldRef ID="{BC91A437-52E7-49E1-8C4E-4698904B2B6D}" Name="LinkTitleNoMenu" 
                DisplayName="Product Code" Sealed="TRUE" />
      <FieldRef ID="{30C3D21A-A7C9-410E-A896-82875475F697}" Name="ProductName" 
                DisplayName="Product Name" Required="False" />
      <FieldRef ID="{9621763e-3494-4a86-a3eb-fd2593f1a1f1}" Name="ProductDescription" 
                DisplayName="Product Description" Required="False" />
    </FieldRefs>
    <XmlDocuments>
      <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
        <FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
          <Display>_layouts/blogtest/Product.aspx?mode=display</Display>
          <Edit>_layouts/blogtest/Product.aspx?mode=edit</Edit>
          <New >_layouts/blogtest/Product.aspx?mode=new</New>
        </FormUrls>
      </XmlDocument>
    </XmlDocuments>
  </ContentType>
</Elements>
Figure 3: Content Type xml file with fields and add/edit/display form declared

Now let’s explain what’s in the xml shown in figure 3.
  • Firstly I’ve modified Inherits to false in ConentType tag.
  • I’ve defined two fields inside the <Elements> tag that I’ve used later in content types
  • Then used those fields in <FieldRefs> of <ContentType> tags. These fields will be available in Content type. I’ve also used three existing fields (for Title) from base Content Type (Item).
  • Finally I’ve defined New, Edit and Display form for these content types in <XmlDocuments> section.


Step 2: Create a list Template based on Content type

Now you have defined content types with three fields. Next step is to define a list template based on the content type. To do so click add new item from visual studio context menu and select “List Definition From Content Type” as shown below:
image
Figure 4: Create list definition from content type in ‘Create new Item’ dialog.

Next you will be prompted for available  content types in the project as shown below. Remember to uncheck the button ‘Add a list instance for this list definition’ for this demo now.
image
Figure 5: Create list definition from Content Type

Now you will find two files Elements.xml and Schema.xml files are added. Our full focus will be now on Schema.xml.

Modify the content in <Fields> tag:
Ensure Title fields with display name ‘product code’ exists as shown below:
<Field ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="Product Code" Sealed="TRUE" Type="Text" />

image
Figure 6: Add title field in the list template (if not exists)

Then find two fields LinkTitle and LinkTitleNoMenu. Then change their display name to ‘Product Code’ as shown below. These two fields are link to edit menu.
image
Figure 7: Rename the displayName for linkTitle and LinkTitleNoMenu field

Modify the content in <Views> tag
Open the views tag and add the fields you want to display in default view under <View> with Default value is true as shown below.
image
Figure 8: Define the fields to be shown in default view

 

 

Step 3: Create Custom add/edit/display form

Next step is to develop a custom application page to use for add/edit/display. As sown in figure 3, you can three different pages for add, edit and view. However for brevity I want to use a single page for all these three operations. You need to create an application page in appropriate location (in my case this is _layouts/blogtest folder). Rather than using three different files for add/edit/display, you can use a single page for all these three tasks as shown below:
<XmlDocuments>
  <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
    <FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
      <Display>_layouts/blogtest/Product.aspx?mode=display</Display>
      <Edit>_layouts/blogtest/Product.aspx?mode=edit</Edit>
      <New >_layouts/blogtest/Product.aspx?mode=new</New>
    </FormUrls>
  </XmlDocument>
</XmlDocuments>

By passing different parameter to a single page we can identity the page’s mode (add, edit or view). Also SharePoint by default add the list and item id at the end of the page. So your page’s url will look like for new item:
_layouts/blogtest/Product.aspx?mode=new&List=LISTGUID&ID=ITEMID
So from the page (Product.aspx) you can identity the list id and item id from querystring.
I’m not showing details of the product.aspx page here.
You can download the full source code from this skydrive link.

How to use the project attached with this post?

  1. Download the code from here.
  2. Deploy the solution to a SharePoint site.
  3. Create a new list with “ProductListDefinition” template. This template will be installed in the site as you deploy the SharePoint solution.
  4. Now try to add/edit/view items in the list. You will find the custom form product.aspx is used for add/edit/view.

Hope some persons might find the post useful..

Tuesday, June 7, 2011

SharePoint: Disable Event Receiver From non-receiver code

When we are in List Item Event Receiver code, we can modify/update the same item which will fire the event receiver again. For disabling event receiver to get fired again we can use the property ‘’ as shown below:

public class TestEventReceiver:SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
//disable event receiver firing
EventFiringEnabled = false;


//do something



//enalbe event receiver firing
EventFiringEnabled = true;

}
}
Figure 1: Sample code to enable/disable event receiver firing inside event receiver handler.

However, if you are in a webpart and want to modify an item but don’t want to fire event receiver, then? Don’t worry there’s a way out. I’ll explain this today.

 

What happens when Event Receiver disabled?

When you disable event receiver, SharePoint internally set a data field in current Thread. So if you can set your current’s thread’s data to the required value before/after updating item, you can control the event receiver. However, setting current thread data manually might be risky and I’ll not use that path. Rather I’ll show how we can use existing power of ‘SPEventReceiverBase’ to control event receiver firing.

 

Create your own Event Receiver Controller

I’ve create a custom class inherited from ‘SPEventReceiverBase’. From this base class I get a properties ‘EventFiringEnabled’ which allows me to control the event receiver firing. The following code snippet shows my custom EventReceiverManager:

public class EventReceiverManager : SPEventReceiverBase, IDisposable
{
public EventReceiverManager(bool disableImmediately)
{
EventFiringEnabled = !disableImmediately;
}

public void StopEventReceiver()
{
EventFiringEnabled = false;
}
public void StartEventReceiver()
{
EventFiringEnabled = true;
}

public void Dispose()
{
EventFiringEnabled = true;
}
}
Figure 2: A EventReceiverManager custom class to control event receiver firing.

The code snippet above is derived from SharePoint’s SPEventReceiverBase to use the ‘EventFireingEnabled’ property.

 

Now you can use this EventReceiverManager to control the event receiver. To stop firing the event receiver on any changes, you need to wrap the code block inside EventReceiverManager as shown below:

using (var eventReceiverManager = new EventReceiverManager(true))
{
var list = GetList("listName");
var listItem = list.GetItemById(itemId);
listItem["field"] = "value";
listItem.Update();
}
Figure 3: How to use EventReceiverManager to disable event receiver firing.
 

As shown above even if he list has event receiver for ItemUpdated/ItemDating the event receiver will not get fired because of putting the code in EventReceiverManager block. Please notice of ‘using’ block, as soon as you leave the ‘using’ block, the event firing in enabled automatically. This is because in Dispose method of EventReceiverManager I’ve enabled the event firing.