1

I have a requirement to build a Event web part that shows the 5 most upcoming events and a see all link (that links to the OOTB calendar view). Here is a graphical representation: Event Web Part

How exaclty do I go about retrieving these items (which list am I looking at) and what web part (Visual web part...etc.) would best fit this? Thanks

Here is the code I have:

protected void Page_Load(object sender, EventArgs e) {

        string siteUrl = "http://sharepointdev:2000/"; //your site url
        using (SPSite oSPSite = new SPSite(siteUrl))
        {
            using (SPWeb oSPWeb = oSPSite.OpenWeb())
            {
                oSPWeb.AllowUnsafeUpdates = true;
                SPList oSPList = oSPWeb.Lists["Calendar"];

                SPQuery oSPQuery = new SPQuery();
                oSPQuery.Query = "<Where><And><Geq><FieldRef Name='EventDate' /><Value IncludeTimeValue='TRUE' Type='DateTime'><now /></Value></Geq><IsNotNull><FieldRef Name='Title' /></IsNotNull></And></Where><OrderBy><FieldRef Name='EventDate' Ascending='True' /></OrderBy>";
                oSPQuery.RowLimit = 3;
                SPListItemCollection oSPListItemCollection = oSPList.GetItems(oSPQuery);

                System.Data.DataTable table = new System.Data.DataTable();
                table = oSPListItemCollection.GetDataTable();
                table.AcceptChanges();
                eventRepeater.DataSource = table;
                eventRepeater.DataBind();

                oSPWeb.Close();
                oSPSite.Close();

            }
        }
    }
}

}

     <asp:UpdatePanel ID="UpdatePanel1" runat="server">
 <ContentTemplate>
 <asp:Repeater ID="eventRepeater" runat="server">
 <ItemTemplate>
   <asp:Label ID="Date" runat="server" CssClass="dateStyle"  Text="<%# DataBinder.Eval  (Container.DataItem, "") %>"></asp:Label><br />
     <asp:Label ID="Title" runat="server" CssClass="titleStyle" Text="<%# DataBinder.Eval(Container.DataItem, "Title") %>"></asp:Label><br />
     <asp:Label ID="Description" runat="server" CssClass="descriptionStyle"  Text="<%# DataBinder.Eval(Container.DataItem, "Description") %>"></asp:Label><br />
   </ItemTemplate>
   </asp:Repeater>
  </ContentTemplate>
  </asp:UpdatePanel>
5
  • Do you need to account for Recurring Items? If so this will become tricky. Also, your mock up seems to indicate that all events from a given day will occur at the same time. What would this look like if Event X2 (Today) occurred at a different time than Event X? Similar to your other question, this might be achievable using an XSLT List View Web Part with some heavily customized XSL. Just depends on how well you know or can pickup (and also maintain) the XSL.
    – Brian
    Mar 22, 2012 at 3:36
  • Hey Brian apologize for the mock up. The show time is across each event and not the date. I thought you might want to take a look at my code and tell me if I could just go with this. I have used a repeater control with 3 labels in an item template.I am having trouble though with the syntax in trying to actually get the data to go into the labels. please note that the all content within text="" of the controls is just what I found of the net and doesnt work.Could you please provide me with an example and explanation on how I could go about doing it?
    – user7400
    Mar 22, 2012 at 13:00
  • I have added the code to the first post. Please take a look. Thanks
    – user7400
    Mar 22, 2012 at 13:03
  • can u try <%#Eval("Title")%> and <%#Eval("Description")%> instead? and can u check while debugging that eventRepeater contains data after the databind() operation?
    – Deepu Nair
    Mar 22, 2012 at 17:21
  • Deepu I am pretty new to this. I am assuming I could do this by putting breakpoints at These two lines eventRepeater.DataSource = table; eventRepeater.DataBind(); I had to remove the table.acceptchanges(); as it was throwing an error and had to remove the update panel I had my controls wrapped in as it was preventing sharepoint from displaying its update panel when I try to edit the page. Please advise Thanks
    – user7400
    Mar 22, 2012 at 18:58

2 Answers 2

1

The code you have provided, written as is, will NOT account for recurring events. Recurring events are a special case in calendars.


Note: A Calendar list is really an "Events" list. It's default view happens to be a calendar view. You can apply a Calendar view to just about any type of list, including custom lists, you need only provide fields that map to the Start/End date (and time if appropriate). You also must configure the Display Title column mapping for the Month, Week, and Day views. Here are SOME features you miss by not using a Calendar (aka Events) LIST:

  • Ability to do calendar overlays
  • Ability to do recurring items (at least not easily)
  • Integration with Outlook calendars

If in your scenario you would not have an "event" that is recurring, I'd recommend hiding the Recurrence field. You can do this through the server side API (object model) or using a tool like SharePoint Designer (http://www.rightpoint.com/community/blogs/viewpoint/archive/2011/10/27/how-to-hide-the-workspace-checkbox-on-a-calendar-without-code-or-form-customization.aspx). This cannot be done through the web based interface as of SP 2010 SP1 + February 2012 CU. Otherwise, you might consider building a custom list with your event details and just building a Calendar view on top of it.

Now, assuming you DO need to account for Occurrences, you need to account for a few things in your code.

First, you need to set the SPQuery.ExpandRecurrence property.

oSPQuery.ExpandRecurrence = true;

Then in your Query CAML, you then need to use the element in your clause. This is the closest thing I could get to what you might need (again depending on requirements around if you want to show recurring items, should you be showing events that currently are happening, should you show events from earlier in the day today, etc):

<Or>
 <Geq>
   <FieldRef Name='EventDate' />
   <Value IncludeTimeValue='TRUE' Type='DateTime'>
     <Today />
   </Value>
 </Geq>
 <DateRangesOverlap>
   <FieldRef Name='EventDate' />
   <FieldRef Name='EndDate' />
   <FieldRef Name='RecurrenceID'/>
   <Value IncludeTimeValue='TRUE' Type='DateTime'>
    <Now />
   </Value>
  </DateRangesOverlap>
</Or>

I would use this as a reference: Query Schema: http://msdn.microsoft.com/en-us/library/ms467521.aspx

It's worth mentioning, again, that the rendering could be accomplished using XSL, rather than a web part. So assuming you could get a SPView on the list that contains the query that correctly filters/sorts your data, you can simply apply a custom XSL to the List View Web Part (or to the View itself), and accomplish the rendering without the need for a Web Part (and Repeater, etc).

1
  • Thanks for the post on how to include recurring events. However for now I have created a web part without it. I have posted the final code.
    – user7400
    Mar 27, 2012 at 20:29
0

At last! Here is the final code: enter image description here

enter image description here


Announcement Web Part code:

  protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            SPWeb web = SPContext.Current.Web;
            web.AllowUnsafeUpdates = true;
            SPList list = web.Lists["Announcements"];

            SPQuery spQuery = new SPQuery();
            spQuery.Query = " <Where><And><IsNotNull><FieldRef Name='Title' /></IsNotNull><Or><IsNull><FieldRef Name='Expires' /></IsNull><Geq><FieldRef Name='Expires' /><Value Type='Date'><Today /></Value></Geq></Or></And></Where><OrderBy><FieldRef Name='Expires' Ascending='True' /></OrderBy>";
            spQuery.RowLimit = 5;
            SPListItemCollection oListCollection = list.GetItems(spQuery);
            System.Data.DataTable table = new System.Data.DataTable();
            table = oListCollection.GetDataTable();

            repAnnouncements.ItemDataBound += new RepeaterItemEventHandler(repAnnouncements_ItemDataBound);
            repAnnouncements.DataSource = table;
            repAnnouncements.DataBind();
        }
        catch (Exception ex)
        {
            throw ex;
        }

}

   void repAnnouncements_ItemDataBound(object sender, RepeaterItemEventArgs e)
   {
   try
   {
   SPListItem item = (SPListItem)e.Item.DataItem; 
   SPAttachmentCollection attachments = item.Attachments;
    ((HyperLink)e.Item.FindControl("hypTextEditLink")).NavigateUrl = SPContext.Current.Site.RootWeb.Url + "/Lists/Announcements/DispForm.aspx?ID=" + ((HiddenField)e.Item.FindControl("ItemID")).Value;

    string imageUrl = item.Web.Url + "/_layouts/images/defaultannouncementimage.png";
    ((Image)e.Item.FindControl("imgLink")).ImageUrl = imageUrl;
if (attachments.Count > 0) 
{         
    //imageUrl = SPUrlUtility.CombineUrl(item.Attachments.UrlPrefix, item.Attachments[0]);
    imageUrl= attachments.UrlPrefix + attachments[0];
    ((Image)e.Item.FindControl("imgLink")).ImageUrl = imageUrl;
}
((HyperLink)e.Item.FindControl("hypImageEditLink")).NavigateUrl = SPContext.Current.Site.RootWeb.Url + "/Lists/Announcements/DispForm.aspx?ID=" + ((HiddenField)e.Item.FindControl("ItemID")).Value;
}
catch (Exception ex)
{ throw ex; }
2
  • Alternatively, in the ItemDataBound event, cast your e.DataItem to an SPListItem. Then you can reference the ListItem.ID property rather than having to make use of a Hidden field and bloating your markup that will be rendered to the browser.
    – Brian
    Mar 29, 2012 at 15:19
  • @Brian I did try following just that in my announcements web part but it would throw me an error. I have appended the details and code to my original post. Thanks
    – user7400
    Mar 29, 2012 at 19:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.