blog.scoreman.net

Posts Tagged ‘WSS 3.0’

Week numbers in SharePoint monthly calendar view

Tuesday, June 23rd, 2009

For some organizations working with week number is very important. Although you can turn on showing week numbers in the Date Navigator under Regional Settings there will be no week numbers showing in the monthly view of the calendar. My goal was to have week numbers printed like in the image below.

This is how I did it.

Step 1: Override CalendarViewmonthChrome template

SharePoint uses different templates to render the different views(day, week, month) of a calendar. In order to change the way the monthly view gets rendered you need to add a custom ascx file to the CONTROLTEMPLATES folder i the 12-hive. This file needs to override the CalendarViewmonthChrome rendering template. What I have done is to copy the default rendering template and replaced the MonthlyCalenderView control with my own MyMonthlyCalendarView.

<%@ Control Language="C#"   AutoEventWireup="false" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.WebControls"%>
<%@ Register TagPrefix="SPHttpUtility" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.Utilities"%>
<%@ Register TagPrefix="wssuc" TagName="ToolBar" src="~/_controltemplates/ToolBar.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ToolBarButton" src="~/_controltemplates/ToolBarButton.ascx" %>
<%@ Register TagPrefix="myControls" Namespace="MyNamespace" Assembly="MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=XXXXXXXXXXX" %>
<SharePoint:RenderingTemplate ID="CalendarViewmonthChrome" runat="server">
  <Template>
    <div id=MontlyViewDefault_CalendarView style="display:block; overflow:auto; width:<%# SPHttpUtility.HtmlEncode(DataBinder.Eval(Container,"ChromeWidth",""))%>; height:<%# SPHttpUtility.HtmlEncode(DataBinder.Eval(Container,"ChromeHeight",""))%>; "  dir="<%# DataBinder.Eval(Container,"Direction","")%>">
    <input type=hidden id=ExpandedWeeksId name=ExpandedWeeks value="">
    <table border=0 width=100% id="CalViewTable1" style="border-collapse: collapse"  cellpadding=0>
      <tr><td><IMG SRC="/_layouts/images/blank.gif" width=742 height=1 alt=""></td></tr>
      <tr>
         <td>
         <table border="0" width="100%" cellspacing="1" cellpadding="0" id="CalViewTable12" style="border-collapse: collapse">
          <tr>
            <td nowrap>
              <div nowrap>
                <a href="javascript:MoveToViewDate('<%# DataBinder.Eval(Container,"PreviousDate","") %>', null);" tabindex=1 style="visibility:<%# DataBinder.Eval(Container,"PreviousDateVisible","")%>" accesskey="<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,calendar_prev_AK%>' EncodeMethod='HtmlEncode'/>">
                <img border="0" src="/_layouts/images/prevbutton<%# DataBinder.Eval(Container,"Direction","")%>.gif" width="15" height="15" alt="<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,calendar_prevmonth%>' EncodeMethod='HtmlEncode'/>" ></a>
                 <a href="javascript:MoveToViewDate('<%# DataBinder.Eval(Container,"NextDate","") %>', null);" tabindex=1 style="visibility:<%# DataBinder.Eval(Container,"NextDateVisible","")%>" accesskey="<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,calendar_next_AK%>' EncodeMethod='HtmlEncode'/>" >
                <img border="0" src="/_layouts/images/nextbutton<%# DataBinder.Eval(Container,"Direction","")%>.gif" width="15" height="15" alt="<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,calendar_nextmonth%>' EncodeMethod='HtmlEncode'/>" ></a>
                &nbsp;<%# DataBinder.Eval(Container,"HeaderDate","") %>&nbsp;
               </div>
            </td>
            <td>&nbsp;</td>
            <tdDirection","")%>">
              <span id=ExpandAllId dir="<%# DataBinder.Eval(Container,"Direction","")%>">
                <a href="javascript:" onclick="javascript:GetMonthView('1111111');return false;" tabindex=1 accesskey="<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,calendar_expandall_AK%>' EncodeMethod='HtmlEncode'/>" nowrap ><NOBR><SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,calendar_expandall%>" EncodeMethod='HtmlEncode'/></NOBR></a>
              </span>
              &nbsp;
              <span id=CollapseAllId dir="<%# DataBinder.Eval(Container,"Direction","")%>">
                <a href="javascript:" onclick="javascript:GetMonthView('0000000');return false;" tabindex=1 accesskey="<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,calendar_collapseall_AK%>' EncodeMethod='HtmlEncode'/>" nowrap ><NOBR><SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,calendar_collapseall%>" EncodeMethod='HtmlEncode'/></NOBR></a>
              </span>
              <span> &nbsp;|</span>
              <Sharepoint:SPCalendarTabs runat="server"
              SelectedViewTab='<%# SPHttpUtility.HtmlEncode(DataBinder.Eval(Container,"ViewType","")) %>'
              ListName='<%# SPHttpUtility.HtmlEncode(DataBinder.Eval(Container,"ListName","")) %>'
              ViewGuid='<%# SPHttpUtility.HtmlEncode(DataBinder.Eval(Container,"ViewName","")) %>'
              >
              </Sharepoint:SPCalendarTabs>
            </td>
          </tr>
        </table>
         </td>
      </tr>
      <tr>
        <td>
          <myControls:MyMonthlyCalendarView runat="server"
          SelectedDate='<%# DataBinder.Eval(Container,"SelectedDate","") %>'
          ExpandedWeeks='<%# SPHttpUtility.HtmlEncode( DataBinder.Eval(Container,"ExpandedWeeks","")) %>'
          ItemTemplateName="CalendarViewMonthItemTemplate"
          ItemAllDayTemplateName="CalendarViewMonthItemAllDayTemplate"
          ItemMultiDayTemplateName="CalendarViewMonthItemMultiDayTemplate"
          TabIndex=2
          >
          </myControls:MyMonthlyCalendarView>
        </td>
      </tr>
     </table>
    </div>
  </Template>
</SharePoint:RenderingTemplate>

Step 2: Intercepting and rewriting html output

The rendering of the table cell where I wanted to insert the week number is well hidden in the MonthlyCalendarView control. What I did instead was to override the AppendEmptyTD and AppendEventTD methods and checked if it was the first day in the week. If so I knew that the StringBuilder object would contain some html with an empty image tag that had an alt-attribute containing text for the week span. Using a regular expression I replaced the image tag with the week number for the current date. Notice that the function that gets the week number is somewhat hard coded and could be rewritten so that Regional Settings for the SPWeb is taken into account.


public class MyMonthlyCalendarView : MonthlyCalendarView
{
    private static Regex weekRegex = new Regex(@"<img border=0 src='/_layouts/images/blank.gif' class='ms-cal-blankimage' alt='[a-z]+s[0-9]{2}s-s[a-z]+s[0-9]{2}'>", RegexOptions.IgnoreCase | RegexOptions.Multiline);

    protected override void AppendEmptyTD(ref StringBuilder str, int iday, Microsoft.SharePoint.Utilities.SimpleDate currDateInWeek)
    {
        if (iday == 0)
        {
            this.AppendWeekNumber(ref str, currDateInWeek);
        }
        base.AppendEmptyTD(ref str, iday, currDateInWeek);
    }

    protected override void AppendEventTD(ref StringBuilder str, int iday, SPCalendarItemContainer oEvent, int colspan, int rowspan, Microsoft.SharePoint.Utilities.SimpleDate currDateInWeek, int tabIndex)
    {
        if (iday == 0)
        {
            this.AppendWeekNumber(ref str, currDateInWeek);
        }
        base.AppendEventTD(ref str, iday, oEvent, colspan, rowspan, currDateInWeek, tabIndex);
    }
   
    private void AppendWeekNumber(ref StringBuilder str, Microsoft.SharePoint.Utilities.SimpleDate currDateInWeek)
    {
        string content = str.ToString();         
        if (weekRegex.IsMatch(content))
        {               
            int week = GetWeekNumber(currDateInWeek);
            content = weekRegex.Replace(content, week.ToString());
            str = new StringBuilder(content);
        }
    }

    private static int GetWeekNumber(SimpleDate date)
    {
        CultureInfo culture = SPContext.Current.Web.Locale;
        return culture.Calendar.GetWeekOfYear(new DateTime(date.Year, date.Month, date.Day), CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    }
}

CAML query with “Today” that includes time value

Tuesday, February 17th, 2009

I was trying to create a CAML query that would filter out all pages with a valid publishing date (and time) using the CrossListQueryInfo object. When I used the <Today/> element in the query it ignored the time.

I remembered reading some were that you could use <Now/> instead of <Today/> but that didn’t do it.

<Leq>
   <FieldRef Name="PublishingStartDate" Nullable="True" Type="DateTime"/>
   <Value Type="DateTime"><Now/></Value>
</Leq>

It turns out that you should use the <Today/> element but that you also need to add a IncludeTimeValue=TRUE attribute.

<Leq>
   <FieldRef Name="PublishingStartDate" Nullable="True" Type="DateTime"/>
   <Value Type="DateTime" IncludeTimeValue="TRUE"><Today/></Value>
</Leq>

Running SPDisposeCheck on Microsoft.*

Friday, February 6th, 2009

I found it interesting that SPDisposeCheck ignored files and namespaces that started with Microsoft and System. With a little bit of .net reflection I managed to come around the “problem”:

Microsoft.SharePoint.dll 9 varnings
Microsoft.Office.Policy.dll 1 varning
Microsoft.Office.Server.Search.dll 1 varning
microsoft.sharepoint.portal.dll 2 varnings
Microsoft.SharePoint.Publishing.dll 10 varnings
Microsoft.SharePoint.Search.dll 1 varning

Using SharePoint DatePicker inside a custom field type or an application page

Tuesday, February 5th, 2008

I wanted to have a custom field type with a date picker and some additional controls. It wasn’t hard to integrate the standard date picker into a custom field type. Below is an extract of the code I wrote.

<%@ Control Language="C#" Debug="true" %>
<%@Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.WebControls"%>
<SharePoint:RenderingTemplate ID="myFieldControl" runat="server">
    <Template>
        <SharePoint:DateTimeControl ID="myDateTimeControl" DateOnly="True" runat="server"></SharePoint:DateTimeControl>
    </Template>
</SharePoint:RenderingTemplate>

 

public override object Value
{
    get
    {
        EnsureChildControls();

        if (!myDateTimeControl.IsDateEmpty)
        {
            return dateTimeTo.SelectedDate;
        }
        else
        {
            return null;
        }
    }

    set
    {
        EnsureChildControls();

        if (value != null)
        {
            myDateTimeControl.SelectedDate = (DateTime)value;
        }
    }
}