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

Wesley Bakker said:

Fun with jQuery and SharePoint. In my previous post I showd how to create a slideshow in SharePoint with the help of jQuery and the Cycle plugin. Yesterday someone asked me for a feature that takes care of opening all external urls in a new window. That

# December 18, 2008 5:00 AM

Mark Chaaban said:

Hello,

I'm trying to use your solution and deploy the slideshow webpart.  I was able to install it and checked all the files in the right place, my problem is when I add the webpart and fill in the List Name and specify the view name I get "An unexpected error has occurred." and it requires me to remove the webpart for my home page to show.  can you help me out, am I missing something?

# December 29, 2008 4:11 PM

webbes said:

Mark,

Unfortunately I can't help you if all I get is "An unexpected error has occured." Could you provide me with more detailed information?

I think it's the list name you provide however. Because it should not be the name of the list but the url to the list. Something like: "serverurl/.../Shared%20Pictures".

Cheers,

Wes

# December 30, 2008 5:58 AM

Mark Chaaban said:

Thank you for the respond,  I fixed the problem,  I was not entering the full URL, I was only entering the Picture Library Name.  When I entered the full URL of the Picture Library I see the Images Rotating.  Thank you this is a great Webpart.

# December 31, 2008 10:22 AM

Sam said:

Hi,

I didn't get the webpart work out(Images are not rotating) though I replaced the files in folder "12" and it's been successfully deployed.

Is it anything to do with PictureCycle.css and PictureCycle.js? Do I have to place them anywhere in my sharepoint folder? as I noticed they are embedded resources.

Any Ideas?

# January 21, 2009 4:50 AM

webbes said:

Hmmm moving around files in folders is something you should not ever need to do in SharePoint. A lot of tutorials and solutions developed by cowboys require that kind of deployment but it's like hacking the registry on windows: Please avoid if you can!

In the zip file you'll find a .wsp file which is a SharePoint Solution Pack. This pack can be installed with stsadm. All files will be automagically deployed in the right folders.

Another thing you could do is download and install WSP builder from: www.codeplex.com/wspbuilder

Once installed you can open my solution, right click it and choose for WSP Builder -> Deploy.

Cheers,

Wes

# January 21, 2009 5:05 AM

Admin's Blog said:

How my team does agile ( Link ) My SharePoint Development Best Practices ( Link ) SharePoint workflow

# January 26, 2009 5:29 AM

Dan said:

I'm not sure if your solution, filtering using ContentTypeId, will work on WSS3. I'm pretty sure it's a different ContentTypeId on WSS3. You can use ContentType = 'Picture', but I'm not sure if that will work on other localizations of WSS3/MOSS.

btw - You can of course use a free slideshow webpart such as http://www.spelements.com/spslideshow/

# February 12, 2009 12:51 PM

webbes said:

@Dan - What a shameless plug of your own free slideshow! But... it looks very good so people should take a look at it :D

btw: It does work on WSS3 but then again, everything on this blog is for free without support.  It only a guidance on how you could built something like it yourself.

# February 13, 2009 2:45 AM

Gary said:

I installed the WSP, activated the features, and added the webpart to the page.  The part didsplays all the images that are in the library.  This is all good, but the images don't rotate?

# March 13, 2009 1:12 PM

Alex said:

should the control be displaying horizontally or vertically?

I am seeing blank space on horizontal and only one image at a time. Can you help me determine if I set did something wrong?

Thanks

Alex

# March 27, 2009 3:13 PM

JohnH said:

I used WSP Builder to build/deploy - that worked well.

I then pointed the List property to the URL of the PictureLib. However, like Gary mentioned, the first image displays, but other images don't rotate. How to get the images to rotate?

# March 31, 2009 1:57 PM

Sam said:

Thanks for sharing--this is awesome!

# May 8, 2009 4:04 PM

John Bailo said:

I'm using VS.2008 with the SP extensions.

Can I simply set the Debug "Start browser with URL" to my Sharepoint site and use the built in Deploy in VS ?

I am not familiar with adding hive 12 elements to a SP Web part project.   Will your solution auto deploy those features to my Sharepoint Site?

# May 19, 2009 1:40 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)