CODEDIGEST
Home » Articles
Search
 

Technologies
 

Sponsored links
 

CodeDigest Navigation
 

Technology News
No News Feeds available at this time.
 

Community News
No News Feeds available at this time.
 
AJAX Dependent Custom Fields For Sharepoint

By Vimal Kumar
Posted On Jul 21,2008
Article Rating:
Be first to rate
this article.
No of Comments: 8
Category: Sharepoint/ASP.Net Ajax
Print this article.

AJAX Dependent Custom Fields for Sharepoint

Introduction

This article will explain us how to create (taking dependent dropdownlist as an example) and deploy dependent custom fields using ASP.Net AJAX for SharePoint. I use ASP.Net Ajax to develop this custom field. This article will also help us to deploy the custom field on the server. I have also attached the sample code with this article for reference.

Pre-Requisites

The pre-requisites for the AJAX dependent custom fields are,

1. ASP.NET 2.0 AJAX Extensions 1.0.

a.      This component to be installed and configured as per article Installing ASP.NET 2.0 AJAX Extensions 1.0 in Windows SharePoint Services Version 3.0.

b.      This component has to be configured for all the Virtual directories which host the custom fields.


AJAX Dependent Custom Fields

Moving forward, we will see how a custom field can be developed using ASP.Net Ajax framework. As I said earlier, I will use the dependant dropdown as an example and will help you implementing it as custom field for SharePoint.

Components

The component that has the dependent custom Fields are,

1.      Parent Custom Field. (e.g. Category)

2.      Child Custom Field. (e.g. Name)

The following sections will take the Category and Name as an example to create the custom field.


User Control (ASCX File)

This file holds the rendering template for the custom field. For simplicity purposes, I’ve added both of the rendering templates into single file (EnigmaFieldControl.ascx). To deploy this file, please refer to the Deployment Section of this article.

1.      Category User Control

a) Following is the Rendering template for the Category Field Control which will be used in displaying the field control for Category Field Control.

<SharePoint:RenderingTemplate ID="CategoryFieldControl" runat="server">

    <Template>

        <asp:DropDownList ID="ddlCategory" runat="server" />

    </Template>

</SharePoint:RenderingTemplate>

b) Only one DropDownList is added which will be the parent control to trigger the Asynchronous postback.

2.      Name User Control

a)      Following is the Rendering template for the Name Field Control which will be used in displaying the field control for Name Field Control.

<SharePoint:RenderingTemplate ID="NameFieldControl" runat="server">

<Template>

<AJAX:ScriptManager ID="scriptManager" runat="server"/>

<AJAX:UpdatePanel ID="updatePanel" UpdateMode="Conditional" runat="server">

<ContentTemplate>

<asp:DropDownList ID="ddlNames" runat="server">

<asp:ListItem>--Select--</asp:ListItem>

</asp:DropDownList>

<AJAX:UpdateProgress AssociatedUpdatePanelID="updatePanel" runat="server" DynamicLayout="true" ID="updateProgress">

<ProgressTemplate>

<div id="divTag" runat="server">Loading...</div>

</ProgressTemplate>

</AJAX:UpdateProgress>

</ContentTemplate>

</AJAX:UpdatePanel>  

</Template>

</SharePoint:RenderingTemplate>

b)      It contains the ScriptManager, UpdatePanel, and UpdateProgess inside which all the controls are embedded.

c)       The child DropDownList ddlNames is embedded inside the ContentTemplate of the UpdatePanel, so that it is enabled for Asynchronous updates (partial page loading).

d)      Also, reference to the System.Web.Extentions (required for ScriptManager, UpdateProgress and UpdatePanel) is done on the ASCX control.


Category Custom Field

1.                  Custom Field Type

a)      The “CategoryFieldType” class here will have to inherit from the “SPFieldText” class since we are going to store the value as a single line of text here.

b)      It has a standard layout of coding with two constructors which are mandatory.

//These constructors are mandatory.

public CategoryFieldType(SPFieldCollection fields, string fieldName)

: base(fields, fieldName)

{

}

 

public CategoryFieldType(Microsoft.SharePoint.SPFieldCollection fields, string typeName, string displayName)

: base(fields, typeName, displayName)

{

}

c)       This function is used to hold any validations, massaging values before it is stored in the list/document library.

//GetFieldValue

public override object GetFieldValue(string value)

{

if (String.IsNullOrEmpty(value))

return null;

//Any other code before saving the value for this field

return value;

}

 

d)      FieldRenderingControl property takes care of actual loading of the field control when the list edit page or Add new page is loaded.

public override BaseFieldControl FieldRenderingControl

{

get

{

//Render the BaseField Control

BaseFieldControl objCategoryFieldControl= new CategoryFieldControl();

objCategoryFieldControl.FieldName = InternalName;

return objCategoryFieldControl;

}

}

 

2.      User Control Code File

a)      DefaultTemplateName property tells us which Rendering Template should be loaded when the control gets loaded. This Rendering template is available in the ASCX file which i have created earlier.

//Default Template Name

protected override string DefaultTemplateName

{

get

{

//Give the rendering template id from the .ascx file

return "CategoryFieldControl";

}

}

b)      The Value Property handles setting and getting the value to and from the control on Edit and Add Pages of List/Document Library respectively.

//To Get and set the items in the ListBox

public override object Value

{

//To Get the Value from the Control and Store in ListItem

get

{

EnsureChildControls();

ddlCategory = (DropDownList)TemplateContainer.FindControl("ddlCategory");

return ddlCategory.SelectedValue;

}

//To Set the value to the control after getting the value from ListItem

set

{

EnsureChildControls();

ddlCategory = (DropDownList)TemplateContainer.FindControl("ddlCategory");

ddlCategory.SelectedValue = (string)this.Value;

}

}

c)       In CreateChildControls function,

1.      Call the EnsurePanelFix function (justification given later in this article).

2.      Get the references to the DropDownList, one using TemplateContainer.FindControl (as the ddlCategory is within the same control) and the other using FindControlRecursive (justification given later in this article)

3.      Add EventHandler and values for the ddlCategory DropDownList.

4.      Get the ScriptManager reference and register ddlCategory as an AsnychronousPostControl.

protected override void CreateChildControls()

{

try

{

if (Field == null)

return;

base.CreateChildControls();

//To make sure Asynchronous Postback works with out any issues

EnsurePanelFix();

//If the user control is in display mode then return

if (ControlMode == Microsoft.SharePoint.WebControls.SPControlMode.Display)

return;

//Use TemplateContainer.FindControl as its inside same control

ddlCategory = (DropDownList)TemplateContainer.FindControl("ddlCategory");

//Use FindControlRecursive as its outside the control

ddlNames = (DropDownList)FindControlRecursive(this.Page, "ddlNames");

 

//Add the Selected Index Changed Event Handler, and some values to Category Control

ddlCategory.AutoPostBack = true;

ddlCategory.SelectedIndexChanged += new                                           EventHandler(ddlCategory_SelectedIndexChanged);

ddlCategory.Items.Add("Fruits");

ddlCategory.Items.Add("Vegetables");

ddlCategory.Items.Add("Trees");

 

//Get existing Script Mananger

ScriptManager sm = ScriptManager.GetCurrent(this.Page);

//If there is no script Manager, add one

 

if (sm == null)

{

//create new ScriptManager and EnablePartialRendering

sm = new ScriptManager();

sm.EnablePartialRendering = true;

sm.EnableScriptLocalization = true;

//add the ScriptManager as the first control in the Page.Form

this.Controls.AddAt(0, sm);

}

//Register the Asnychronous Post back Control as ddlCategory with script Manager

sm.RegisterAsyncPostBackControl(ddlCategory);

 

}

catch (Exception ex)

{

throw new Exception(ex.Message);

}

}

d)      EnsurePanelFix method is used to resolve an issue in the AJAX Framework and for Asynchronous post back to work.

e)      FindControlRecursive method is used to find a control which is outside the current rendering template.

f)        The SelectedIndexChanged eventhandler for the ddlCategory gets the reference of the UpdatePanel and the ddlNames DropDownList, updates the values in the ddlNames according to the value selected in the ddlCategory DropDownList and calls the update method of the UpdatePanel so that the controls inside it are updated.

//ddlCategory Selected Index Changed

void ddlCategory_SelectedIndexChanged(object sender, EventArgs e)

{

//get references to the controls

updatePanel = (UpdatePanel)FindControlRecursive(this.Page, "updatePanel");

ddlCategory = (DropDownList)TemplateContainer.FindControl("ddlCategory");

ddlNames = (DropDownList)FindControlRecursive(this.Page, "ddlNames");

ddlNames.Items.Clear();

 

//Load the Names dropdownlist based on the Category

switch (ddlCategory.SelectedValue)

{

case "Fruits":

ddlNames.Items.Add("Peach");

ddlNames.Items.Add("Strawberry");

ddlNames.Items.Add("Blueberry");

 

break;

case "Vegetables":

ddlNames.Items.Add("Carrot");

ddlNames.Items.Add("Radish");

ddlNames.Items.Add("Beetroot");

break;

case "Trees":

ddlNames.Items.Add("Banyan");

ddlNames.Items.Add("Neem");

break;

default:

break;

 

}

//refresh the update panel

updatePanel.Update();

}

 

 




Name Custom Field

1.      Custom Field Type

a)       The “CategoryFieldType” class will have to inherit from the “SPFieldText” class as we are going to store the value as a single line of text here.

b)      It has a standard layout of coding with two constructors which are mandatory.

//These constructors are mandatory.

public NameFieldType(SPFieldCollection fields, string fieldName)

: base(fields, fieldName)

{

}

public NameFieldType(Microsoft.SharePoint.SPFieldCollection   fields, string typeName, string displayName)

: base(fields, typeName, displayName)

{

}

c)       This function is used hold any validations, massaging values before it is stored in the list/document library.

//GetFieldValue

public override object GetFieldValue(string value)

{

if (String.IsNullOrEmpty(value))

return null;

//Any other code before saving the value for this field

return value;

}

 

d)      FieldRenderingControl property takes care of actual loading of the field control when the list edit page or Add new page is loaded.

public override BaseFieldControl FieldRenderingControl

{

get

{

//Render the BaseField Control

BaseFieldControl objNameFieldControl = new CategoryFieldControl();

objNameFieldControl.FieldName = InternalName;

return objNameFieldControl;

}

}

 

2.            User Control Code File

a)      This has a similar User Control code file as that of Category Field Control, nothing extra. (As the functions have been clearly explained in category custom field, it would be easy to follow this field control as well).


FLDTypes

1.      The name of the file has to be in the format fldtypes_xxx.xml, and then only SharePoint will recognize it as a custom field.

2.      This file contains the definition of the field type and has the reference to the Field Type Class of both Category and Name custom Field.

<FieldType>

              <Field Name="TypeName">AJAX_Category</Field>

              <Field Name="ParentType">Text</Field>

              <Field Name="TypeDisplayName">AJAX Category</Field>

              <Field Name="TypeShortDescription">AJAX Category</Field>

              <Field Name="UserCreatable">TRUE</Field>

              <Field Name="ShowInListCreate">TRUE</Field>

              <Field Name="ShowInSurveyCreate">TRUE</Field>

              <Field Name="Sortable">TRUE</Field>

              <Field Name="Filterable">TRUE</Field>

              <Field Name="ShowInDocumentLibraryCreate">TRUE</Field>

              <Field Name="ShowInColumnTemplateCreate">TRUE</Field>

<Field Name="FieldTypeClass"> Enigma_CustomFields.CategoryFieldType,Enigma_CustomFields,Version=1.0.0.0, Culture=neutral, PublicKeyToken= f1afff6befa7d3cd</Field>

</FieldType>


Deploying Custom Field

1.      Copy and paste the ASCX file in “C:\Program Files\Common Files\Microsoft Shared\web Server extensions\12\TEMPLATE\CONTROLTEMPLATES”

2.      Deploy the assembly to GAC.

3.      Copy and paste the fldtype file to “C:\Program Files\Common Files\Microsoft Shared\web Server extensions\12\TEMPLATE\XML”

4.      Restart the IIS through iisreset command.

5.      Now, if you go to any list, your custom field will be ready to be added to the list. Make sure that you add both the fields before you start accessing the controls.

Downloads

Download Source

References

For EnsurePanelFix

Create a Custom Field Type & Field Control

Create custom field types for SharePoint

 

Conclusion

Thus, we can now create and deploy a new custom fields using ASP.Net Ajax for SharePoint sites. I have attached the source code in the download section of this article for reference.

Thanks for reading my article! Please post your queries in the feedback section of this article.

 

Similar Articles

You can contribute to CodeDiget.Com:
Donate to CodeDigest.com
Article Feedback
Comments
SharePoint Branding
There are many Intranets solutions on the market, however if you are looking for a solid SharePoint based Intranet solution, check out SharePoint Implementeds' product. I think it's the best solution out for the price.They seem to have put a lot of thought into usability and filling in gaps that you would not know exsist in sharepoint until you start your implementation.

They offer a turnkey solution which provides a custom Home Site, Department Sites and Project Sites, installation, configuration and training all under $10,000 and even have a source code option.

One thing that I would love to see that they don't have now is a hosted solution

You can get more details at http://sharepointimplemented.com/AwesomeIntranetGorilla.html
Thanks!
Nice post! My own FindControlRecursive helped me out many times. Especially, when I deal with MasterPages. For example, one of such usage is shown in my post here – <a href="http://dotnetfollower.com/wordpress/2010/12/sharepoint-add-onchange-attribute-to-dropdownchoicefield/">http://dotnetfollower.com/wordpress/2010/12/sharepoint-add-onchange-attribute-to-dropdownchoicefield/</a>.
Thank you!
More then 2 dropdowns
I am having problem to implement 3 dropdowns in similar manner.Please help.
Thanks in advance
works
It worked but dropdown does refresh if value changes..
Re: Page refresh
Did you call the EnsurePanelFix() function.
Refer to this link.
http://msdn.microsoft.com/en-us/library/bb861877.aspx.

Copy the EnsurePanelFix() from this link and paste it in your code.
Page refresh
I tried implementing ur code on our sharepoint site but your control also refresh page on Category selected index change. I read on net that you update panel is not supported on sharepoint and u need to add javascript code to make it work. Please let me know how to implement your code. If your code will work without refresh then i will create my custom control which will fetch value from sharepoint list.
Page Refresh
Hi, I have used ur control but it refreshes whole page on selected index change of Category dropdown control.
Curious
I am currious if you have implemented this .. instead of hardcoding values through code... to implement it read values from Field Properties or another list.. ? if so adding more than one custom field instance on it?