Wesley Bakker

Interesting things I encounter doing my job...

Sponsors

News

Wesley Bakker
motion10
Rivium Quadrant 151
2909 LC Capelle aan den IJssel
Region of Rotterdam
The Netherlands
Phone: +31 10 2351035

(feel free to chat with me)
 

Add to Technorati Favorites

SharePoint Slideshow Web Part

Slideshow for SharePoint

In two previous posts I demonstrated how you could use wrappers for list items in order to enable strongly typed access to list item properties. Very nice but I can imagine you guys and girls would like to see a real life example of it's usage. And I guess it would be very nice if I could come up with something that we can actually use in our project today. So I decided to create a slideshow web part. With the help of: jQuery, the jQuery Cycle plugin and a PictureWrapper I created a very basic slideshow. It's not completely finished, but I'll leave the addition of some extra options as practice for you guys. If you're not interested in my writing you can download the complete source and the Windows SharePoint Solution Package at the end of this article. It has been created with the help of WSP Builder. The must have tool for all SharePoint developers.

Screenshot

PictureWrapper

To get me started I first had to create a wrapper arround picture items. This wrapper is responsible for returning pictures from a PictureLibrary. To make shure we have all our needed fields I filter on contentTypeId and I make sure the ViewFields contains al the nececary field refrences. If you read the previous articles about wrapping list items this is all straight forward.

internal sealed class PictureWrapper

{

    private static readonly string contentTypedId = "0x010102";

 

    private SPListItem listItem;

    internal PictureWrapper(SPListItem listItem)

    {

        if (listItem == null)

        {

            throw new ArgumentNullException("listItem");

        }

 

        this.listItem = listItem;

    }

 

    internal static string ContentTypeId

    {

        get

        {

            return contentTypedId;

        }

    }

 

    internal string NameOrTitle

    {

        get

        {

            return listItem.GetValue<string>("NameOrTitle", string.Empty);

        }

    }

 

    internal string Url

    {

        get

        {

            return listItem.GetValue<string>("Url", string.Empty);

        }

    }

 

    internal string ThumbnailUrl

    {

        get

        {

            return listItem.GetValue<string>("EncodedAbsThumbnailUrl", string.Empty);

        }

    }

 

    internal string WebImgUrl

    {

        get

        {

            return listItem.GetValue<string>("EncodedAbsWebImgUrl", string.Empty);

        }

    }

 

    internal static IEnumerable<PictureWrapper> GetItems(string listUrl, string viewName)

    {

        if (string.IsNullOrEmpty(listUrl))

        {

            throw new ArgumentNullException("listUrl");

        }

 

        SPList itemsList = CycleHelper.GetListByUrl(listUrl);

        SPView itemsView = null;

 

        if (!string.IsNullOrEmpty(viewName))

        {

            itemsView = itemsList.Views[viewName];

        }

 

        if (itemsView == null)

        {

            itemsView = itemsList.DefaultView;

        }

 

        SPQuery query = new SPQuery(itemsView);

        query.Query = string.Format(CultureInfo.InvariantCulture,

                                    "<Where><BeginsWith><FieldRef Name='ContentTypeId'/><Value Type='Text'>{0}</Value></BeginsWith></Where>",

                                    ContentTypeId);

 

        query.ViewFields = "<FieldRef Name='NameOrTitle'/><FieldRef Name='Url'/><FieldRef Name='EncodedAbsThumbnailUrl'/><FieldRef Name='EncodedAbsWebImgUrl'/>";

 

 

        SPListItemCollection items = itemsList.GetItems(query);

 

        foreach (SPListItem item in items)

        {

            yield return new PictureWrapper(item);

        }

    }

}

Using the PictureWrapper

Since we have a PictureWrapper we can access our properties strongly typed. Which is what we'll do in our PictureCycle web part. The web part generates an unordered list with which the Cycle plugin can create a slideshow. Access to our properties is really as simple as this.

foreach (PictureWrapper wrapper in pictureListItems) {

    HtmlGenericControl li = new HtmlGenericControl("li");

    HtmlImage img = new HtmlImage();

    img.Alt = wrapper.NameOrTitle;

    img.Attributes.Add("title", img.Alt);

 

    img.Src = (Size == DisplaySize.WebImage) ? wrapper.WebImgUrl : wrapper.ThumbnailUrl;

 

    li.Controls.Add(img);

    _container.Controls.Add(li);

}

jQuery and the Cycle plugin

Our PictureCycle web part uses both jQuery and the Cycle plugin and it took me a while to figure out a decent way of implementing both in our solution. I do not want every control to register jQuery or the plugins. So I decided to create two seperate features for taking care of that. I took the great example of mister Tielens and enhanced it a little bit by adding the Sequence attribute to the Control Element like so:

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

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

  <Control

    Id="AdditionalPageHead"

    ControlSrc="~/_controltemplates/jQuery/jQuery126Control.ascx"

    Sequence="0"/>

</Elements>

With the Sequence attribute we ensure ourselves that the jQuery script is being added to the header before our plugins which get a Sequence of anything greater than 0

Another thing we need to do is make sure that we activate our features in the correct order. This can be done very simple by adding feature activation dependencies. The Cycle plugin depends on jQuery so we add the FeatureId of our jQuery feature as an activation dependency to our Cycle plugin feature like so:

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

<Feature  Id="9da8615f-49d1-4d14-b3d3-35f6e45ec16b"

          Title="motion10 jQuery Cycle Plugin"

          Description="This feature adds the jQuery Cycle Plugin to your site."

          Version="12.0.0.0"

          Hidden="FALSE"

          Scope="Site"

          DefaultResourceFile="core"

          Creator="Wesley Bakker"

          ImageUrl="motion10/FeaturesIcon.png"

          ImageUrlAltText="http://www.motion10.com"

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

  <ActivationDependencies>

    <ActivationDependency FeatureId="f805f632-a321-435c-9d13-025454e3fd5a"/>

  </ActivationDependencies>

  <ElementManifests>

    <ElementManifest Location="elements.xml"/>

  </ElementManifests>

</Feature>

A lot more...

Of course there is a lot more in the download. We need some javascript to enable the creation of slideshows in one simple line. We need some styling as well. Both the script and the styling are added as embedded resources. Just as an example on how you could accomplish something like that.

So far for now. Please leave comments if you like it or when you see room for improvement.

Cheers,

Wes

Comments

No Comments