Sunday, February 7, 2010

A custom rendering template for the Calendar View control

Q: How do I create a custom rendering template that only affects one calendar view on the site?

A: In Microsoft Office SharePoint Server 2007 and WSS 3.0 it is possible to use a custom view style with the SPCalendarView control, so that additional views or replacements for the default views (Day, Week, Month) can be rendered by a custom RenderingTemplate.

This functionality is provided by using the undocumented SPCustomViewElement element definition, which may be used to create a custom view feature at the web level, that it turn points to the custom rendering template, e.g.:

<?xml version="1.0" encoding="utf-8"?>

<Solution xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" SolutionId="453b1767-713e-4ca2-80bb-33aa0b40348e" xmlns="http://schemas.microsoft.com/sharepoint/">

  <FeatureManifests>

    <FeatureManifest Location="HubKey.SharePoint\feature.xml" />

  </FeatureManifests>

</Solution>

<?xml version="1.0" encoding="utf-8" ?>

<Feature  Id="EE647B50-1408-4ac7-9B8F-27D86A2E8985"

          Title="HubKey Calendar View Feature"

          Description="Adds calendar custom view."

          Version="1.0.0.0"

          Creator="http://www.hubkey.com"

          ActivateOnDefault="True"

          Scope="Web"

          xmlns="http://schemas.microsoft.com/sharepoint/">

  <Properties>

    <Property Key="GloballyAvailable" Value="true" />

  </Properties>

    <ElementManifests>

        <ElementManifest Location="elements.xml" />

    </ElementManifests>

</Feature>

<?xml version="1.0" encoding="utf-8" ?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

    <CustomView

        Title="Work Week" 

        Type="workweek" 

        ListType="Events" 

        ListViewType="CALENDAR" 

        Sequence="0" 

        AccessKey="w" 

        ImageHeight="15"

        ImageWidth="15"

        ImageName="week.gif"

        ViewChromeTemplateId="CustomCalendarViewweekChrome">

    </CustomView>

</Elements>



Although this functionality is native to MOSS and WSS 3.0, the definition for SPCustomViewElement may have been omitted from the wss.xsd schema. If this type is missing from the TEMPLATE\XML\wss.xsd file, the addition of a solution with the CustomView element will fail when verified against the schema. To avoid this scenario, the following type definition (highlighted in turquqoise) must be included in the wss schema file. Please note that editing the wss schema file cannot be recommended, please contact your Microsoft representative for more information.

<xs:complexType name="ElementDefinitionCollection">

        <xs:sequence>

            <xs:choice minOccurs="0" maxOccurs="unbounded">

                <xs:element name="ContentType" type="ContentTypeDefinition"/>

                <xs:element name="ContentTypeBinding" type="ContentTypeBindingDefinition"/>

                <xs:element name="DocumentConverter" type="DocumentConverterDefinition"/>

                <xs:element name="FeatureSiteTemplateAssociation" type="FeatureSiteTemplateAssociationDefinition"/>

                <xs:element name="Field" type="SharedFieldDefinition"/>

                <xs:element name="CustomAction" type="CustomActionDefinition"/>

                <xs:element name="CustomActionGroup" type="CustomActionGroupDefinition"/>

                <xs:element name="HideCustomAction" type="HideCustomActionDefinition"/>

                <xs:element name="Module" type="ModuleDefinition"/>

                <xs:element name="ListInstance" type="ListInstanceDefinition"/>

                <xs:element name="ListTemplate" type="ListTemplateDefinition"/>

                <xs:element name="Control" type="DelegateControlDefinition"/>

                <xs:element name="Receivers" type="ReceiverDefinitionCollection"/>

                <xs:element name="Workflow" type="WorkflowDefinition"/>

                <xs:element name="UserMigrator" type="UserMigratorDefinition"/>

                <xs:element name="CustomView" type="CustomViewDefinition"/>

            </xs:choice>

        </xs:sequence>

        <xs:attribute name="Id" type="UniqueIdentifier"/>

    </xs:complexType>

    <xs:complexType name="CustomViewDefinition" mixed="true">

        <xs:attribute name="ViewChromeTemplateId" type="xs:string"/>

        <xs:attribute name="ImageName" type="xs:string"/>

        <xs:attribute name="ImageWidth" type="xs:string"/>

        <xs:attribute name="ImageHeight" type="xs:string"/>

        <xs:attribute name="AccessKey" type="xs:string"/>

        <xs:attribute name="Sequence" type="Sequence"/>

        <xs:attribute name="ListViewType" type="xs:string"/>

        <xs:attribute name="ListType" type="xs:string"/>

        <xs:attribute name="Type" type="xs:string"/>

        <xs:attribute name="Title" type="LocalizableString"/>

    </xs:complexType>



The custom rendering template shown below is copied from the CalendarViewweekChrome template. Use DefaultTabsEnabled=false (highlighted in turquqoise) to replace the default calendar view tabs.

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

    <Template>

     <div id=CustomWeeklyViewDefault_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","")%>" >

      <table border=0 width=300 id="CalViewTable1" style="border-collapse: collapse" cellpadding=0>

            <tr><td class="ms-calheader" ><IMG SRC="/_layouts/images/blank.gif" width=742 height=1 alt=""></td></tr>

            <tr>

               <td class="ms-calheader">

               <table border="0" width="100%" cellspacing="1" cellpadding="0" id="CalViewTable12" style="border-collapse: collapse">

                    <tr>

                        <td nowrap>

                            <div class="ms-cal-navheader" nowrap>

                              <a href="javascript:MoveToDate('<%# DataBinder.Eval(Container,"PreviousDate","") %>');" 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_prevweek%>' EncodeMethod='HtmlEncode'/>" ></a>

                              <a href="javascript:MoveToDate('<%# DataBinder.Eval(Container,"NextDate","") %>');" 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_nextweek%>' EncodeMethod='HtmlEncode'/>" ></a>

                              &nbsp;<%# DataBinder.Eval(Container,"HeaderDate","") %>&nbsp;

                             </div>

                        </td>

                        <td>&nbsp;</td>

                        <td class="ms-cal-nav-buttons<%# DataBinder.Eval(Container,"Direction","")%>">

                          <Sharepoint:SPCalendarTabs ID="SPCalendarTabs1" runat="server" DefaultTabsEnabled=false

                            SelectedViewTab='<%# SPHttpUtility.HtmlEncode(DataBinder.Eval(Container,"ViewType","")) %>'

                            ListName='<%# SPHttpUtility.HtmlEncode(DataBinder.Eval(Container,"ListName","")) %>'

                            ViewGuid='<%# SPHttpUtility.HtmlEncode(DataBinder.Eval(Container,"ViewName","")) %>'

                          >

                          </Sharepoint:SPCalendarTabs>

                        </>

                    </tr>

                </table>

               </td>

            </tr>

            <tr>

            <td>

                <Sharepoint:WeeklyCalendarView ID="WeeklyCalendarView1" runat="server" IsWorkWeek=true

                    SelectedDate='<%# DataBinder.Eval(Container,"SelectedDate","") %>'

                    ItemTemplateName="CalendarViewWeekItemTemplate"

                    ItemAllDayTemplateName="CalendarViewWeekItemAllDayTemplate"

                    ItemMultiDayTemplateName="CalendarViewWeekItemMultiDayTemplate"

                    TabIndex=2

                >

                </Sharepoint:WeeklyCalendarView>

            </td>

            </tr>

         </table>

    </div>

    </Template>

</SharePoint:RenderingTemplate>



The CalendarViewStyles element in the view’s Schema Xml can be used to set the default view, e.g.:

<CalendarViewStyles>

    <CalendarViewStyle Title=' Work Week' Type='workweek' Template='CustomCalendarViewweekChrome' Sequence='0' Default='TRUE'/>

    <CalendarViewStyle Title='Day' Type='day' Template='CalendarViewdayChrome' Sequence='1' Default='FALSE'/>

    <CalendarViewStyle Title='Week' Type='week' Template='CalendarViewweekChrome' Sequence='2' Default='FALSE'/>

    <CalendarViewStyle Title='Month' Type='month' Template='CalendarViewmonthChrome' Sequence='3' Default='FALSE'/>

</CalendarViewStyles>

4 comments:

Anonymous said...

nice post. thanks.

Anonymous said...

Great blog post, been after that :D

Sincere Regards
Joy

westerdaled said...

Hi


Do you have a screen dump / bit map that shows what this looks like?

Daniel

westerdaled said...

Hi


Do you have a screen dump / bit map that shows what this looks like?

Daniel