Archive for the ‘Customization’ Category


Please note this is a post by Albert Meerscheidt in msdn blogs.  I am copying this as is just not to miss this wonderful post in future.

Problem: There are issues with particular field names like ItemName which will be truncated in an alert email at 70 characters. There can also be situations where you want to embed additional content in the email or change the layout and email appearance altogether.

Solution: Make use of the IAlertNotifyHandler interface to intercept the email and modify it.

We can create our own class that inherits from the IAlertNotifyHandler interface and uses theOnNotification method. This will allow you to intercept the outgoing alert emails and modify them. We can access most of the properties for the alert and with some xml parsing and SharePoint object model code, we can extract all the information we need to build up the email. We can then construct the HTML stub to display the email based on your requirements and send the email out using SharePoint’s SendMail functionality.

Steps:

I have included the sample code below along with the steps to set up the scenario. I have formatted the output of my code to resemble the default alert template emails as close as possible, you can customize it further to suit your needs.

1      Create a class project that inhertits from the IAlertNotifyHandler interface. Include the Microsoft.SharePoint and Microsoft.SharePoint.Utilities namespaces in the project.

This is the code for the class:

public class Class1:IAlertNotifyHandler

{

#region IAlertNotifyHandler Members

public bool OnNotification(SPAlertHandlerParams ahp)

{

try

{

SPSite site = new SPSite(ahp.siteUrl+ahp.webUrl);

SPWeb web = site.OpenWeb();

SPList list=web.Lists[ahp.a.ListID];

SPListItem item = list.GetItemById(ahp.eventData[0].itemId) ;

string FullPath=HttpUtility.UrlPathEncode(ahp.siteUrl+”/”+ahp.webUrl+”/”+list.Title+”/”+item.Name);

string ListPath = HttpUtility.UrlPathEncode(ahp.siteUrl + “/” + ahp.webUrl + “/” + list.Title);

string webPath=HttpUtility.UrlPathEncode(ahp.siteUrl+”/”+ahp.webUrl);

string build = “”;

if (ahp.eventData[0].eventType==1)

eventType=”Added”;

else if(ahp.eventData[0].eventType==2)

eventType=”Changed”;

else if(ahp.eventData[0].eventType==3)

eventType=”Deleted”;

build = “<style type=\”text/css\”>.style1 {              font-size: small; border: 1px solid #000000;”+

“background-color: #DEE7FE;}.style2 {               border: 1px solid #000000;}</style></head>”+

“<p><strong>”+ item.Name.ToString() +”</strong> has been “+eventType +”</p>”+

“<table style=\”width: 100%\” class=\”style2\”><tr><td style=\”width: 25%\” class=\”style1\”>”+

“<a href=”+ webPath +”/_layouts/mysubs.aspx>Modify my Settings</a></td>”+

“<td style=\”width: 25%\” class=\”style1\”> <a href=”+ FullPath +”>View “+item.Name+”</a></td>”+

“<td style=\”width: 25%\” class=\”style1\”><a href=” + ListPath + “>View ” + list.Title + “</a></td>” +

”        </tr></table>”;

string subject=list.Title.ToString() ;

SPUtility.SendEmail(web,true , false, ahp.headers[“to”].ToString(), subject,build);

return false;

}

catch (System.Exception ex)

{

return false;

}

}

#endregion

}

2.            GAC the dll.

3.            Make a copy of the alertTemplates.xml file found at this location: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\XML. Always work with a copy of AlertTemplates.xml, not the original.

4.            Call this new file CustomAlertTemplates and save the file. Edit the file and search for the keyword properties:

Include these additional lines into the properties block:

<NotificationHandlerAssembly>AlertHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d59ecf2a3bd66904</NotificationHandlerAssembly>

<NotificationHandlerClassName>AlertHandler.Class1</NotificationHandlerClassName>

<NotificationHandlerProperties></NotificationHandlerProperties>

The entire stub should look like this now:

<Properties>

<ImmediateNotificationExcludedFields>ID;Author;Editor;Modified_x0020_By;Created_x0020_By;_UIVersionString;ContentType;TaskGroup;IsCurrent;Attachments;NumComments;</ImmediateNotificationExcludedFields>

<DigestNotificationExcludedFields>ID;Author;Editor;Modified_x0020_By;Created_x0020_By;_UIVersionString;ContentType;TaskGroup;IsCurrent;Attachments;NumComments;</DigestNotificationExcludedFields>

<NotificationHandlerAssembly>AlertHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d59ecf2a3bd66904</NotificationHandlerAssembly>

<NotificationHandlerClassName>AlertHandler.Class1</NotificationHandlerClassName>

<NotificationHandlerProperties></NotificationHandlerProperties>

</Properties>

Include this xml stub in each alert template section you want in the alert template file.

5.            Run this command from C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN:  stsadm -o updatealerttemplates -filename “C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\XML\customalerttemplates.xml” -url <your sharepoint site url>

6.            Run this command:  stsadm -o setproperty -pn job-immediate-alerts -pv “every 1 minutes” so that you can see the log file come back in one minute. Be sure to set the time back after testing.

7.            Make sure you have SharePoint already configured for outgoing emails.

8.            Make sure that you have alerts for the document library turned on if you are testing with the document library.

9.            Run this command from the command prompt: iisreset

10.         Run this command from the command prompt: services.msc

11.         From the services window, restart the Windows SharePoint Services Timer

.

Actual Post Link : http://blogs.msdn.com/b/sharepointdeveloperdocs/archive/2007/12/14/how-to-customizing-alert-emails-using-ialertnotificationhandler.aspx

Advertisements

When ever we create a view for a list there will be a section called Totals. We can use this section to calculate & display the total of the items in the list. This will be useful to display totals particularly when you use group-by.If you notice, you will be seeing some column names with a drop-down nearby with option “Count”. If you select this the count will be based on this column. But if you are having a calculated column in your list, it will not be displayed here. So in this case we need to create a data view web part using designer. In this case you can do total and other operations like sum etc..

  1. First create a Data view web part and apply grouping if needed (check this post).
  2. Don’t forget to select “Show Group Footer” in the Sort & group properties.
  3. Now you will get the data view displaying the list with totals for each group (as in above picture with count).
  4. If you notice the code related to count is Count : <xsl:value-of select=”count($nodeset)” />

Now I am having another column Man Hours in my list which is of Type Number. I want t0 display the sum of man hours for each group (in my case for each location i need to find the total man hours).

To do so I just replace Count : <xsl:value-of select=”count($nodeset)” /> with Total Man Hours : <xsl:value-of select=”sum($nodeset/@Man_x0020_Hours)” />

Now my list view looks like

You can notice Total Man Hours displaying total man hours for each location. You can try more functions other than Sum 🙂


When you try to export the contents of a list to an excel, things would seem to start working, but then Excel would pop up an error: “Cannot get the list schema column property from the SharePoint list”.

Searching over the internet I got to know its due to the presence of DateTime field in SharePoint which when exported to excel raises a mismatch in data type.  To solve this issue I found 2 ways

  1. Remove the DateTime field from the view you want to export to excel. if you really t want those date columns, then you have to try step 2.
  2. Convert the date field to a single line of text.  Then, convert it back to a date. It was nice to see that the conversion worked, actually.  It was quite nervous that converting things this way would fail, but it did not.

Another way I found is creating a new page, placing a Data View webpart (A fine article on creating Data View Web Part) in at with the data source as your list. This will display all the items in your list. Now open this page in the browser, right click & select Export to excel.


An interesting development.

  • On clicking on the empty brick,a new form opens as a pop-up where he/she can fill the wishes.
  • Once filled the wish with name appears on the brick.
  • After all the bricks are completely filled next button will appear taking you to next wall.
  • On mouse over the message details are shown in a pop-up.

And do you believe?? Its a simple ASP.NET calendar control with some GUI changes a simple logic behind to show the multiple walls.


I used SharePoint People Editor control in custom asp.Net web part.I wanted to check for required field. I have tried using the property Allow Empty, but unfortunately it doesn’t work. I have used a Required field validator. Luckily it works to some extent. But the problem starts if there is any post back happening on the page. After the post back, it takes the value to be empty even if there is an entry in the control.

I got to get a javascript that  checks if the control is empty and stores the results of the validation in the IsValid property of the ServerValidateEventArgs object.

Here is the script and a custom validator we need to use to check e\whether the people editor control is empty or not.

<script type=”text/javascript” language=”javascript”>
function CheckBusinessExcellence(source, arguments)

{
if (aspnetForm.ctl00_PlaceHolderMain_pplBusinessExcellence_downlevelTextBox.value == “”)
arguments.IsValid = false;
else
arguments.IsValid = true;

}

</script>


<sharepoint:peopleeditor ValidatorEnabled=”true” autopostback=”true” rows=”1″ width=”300″ enablebrowse=”true”
id=”pplBusinessExcellence” multiselect=”False” runat=”server” />


<asp:CustomValidator ID=”rfvBusinessExcellence” runat=”server” ControlToValidate=”” ErrorMessage=”You must specify a value for this required field.” Enabled=”false” ClientValidationFunction=”CheckBusinessExcellence”>
</asp:CustomValidator>



And in a more simpler way, I found the normal Required Field validator works fine for me.

<sharepoint:peopleeditor validatorenabled=”true” allowempty=”false”  rows=”1″ width=”300″ enablebrowse=”true”
id=”pplBusinessExcellence” multiselect=”False” runat=”server” />

<asp:RequiredFieldValidator EnableClientScript=”true” ID=”rfvBusinessExcellence” ControlToValidate=”pplBusinessExcellence” runat=”server” ErrorMessage=”You must specify a value for this required field”></asp:RequiredFieldValidator>


Hope it helps.