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

April 2009 - Posts

DownloadAsZip SharePoint Feature RTW

I have to admit. I am late! Much to late! I promised you all a DownloadAsZip feature for SharePoint in a few days and it took me more than a month. But finally it’s here. First have a look at what it’s actually all about.

A picture says so much more

Hover the images for explanation…

Open a document library Apply some filtering Enable item selection Select the items to download Start the download Save the file Watch it complete The result looks like this

 

 

 

 

 

 

 

How did we get to this result?

I’ve explained how to create the multi select button and how to create the download handler in two previous posts. So now I’m going to focus on the last part. The ‘DownloadAsZip’ buttons.

Easy peasy

Let’s start with the easiest part. With the handler in place we can add custom actions to list items simply by adding some CustomAction elements to our Elements manifest file. Here’s what the elements.xml looks like:

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  ...
  <CustomAction
    Id="{18A0608F-7917-4fa3-8164-18E81B55A551}"
    ImageUrl="/_layouts/images/ICZIP.GIF"
    Title="Download as Zip"
    Description="Download all files in this folder and view as one zip"
    RegistrationType="ContentType"
    RegistrationId="0x0120"
    Location="EditControlBlock">
    <UrlAction Url="{SiteUrl}/_layouts/DownloadAsZip.ashx?List={ListId}&amp;Item={ItemId}" />
  </CustomAction>
  <CustomAction
    Id="{175D475D-C962-4965-9C9B-7CAFBB36A669}"
    ImageUrl="/_layouts/images/ICZIP.GIF"
    Title="Download as Zip"
    Description="Download this file as zip"
    RegistrationType="ContentType"
    RegistrationId="0x0101"
    Location="EditControlBlock">
    <UrlAction Url="{SiteUrl}/_layouts/DownloadAsZip.ashx?List={ListId}&amp;Item={ItemId}" />
  </CustomAction>
</Elements>

What this fragment does is that it adds two buttons to the edit control block. One for files (RegistrationId=”0x0101”) and one for folders (RegistrationId=”0x0120”). These custom actions simply redirect the client to the previously created DownloadAsZip.ashx with the correct query string values.

So this adds single item DownloadAsZip functionality to our SharePoint site.

singledownload

Little bit more difficult

The code for the DownloadAsZip button on the ListView level is somewhat more difficult but still not to complicated. The code looks like this:

//-----------------------------------------------------------------------
// <copyright file="DownloadAsZipAction.cs" company="motion10">
//     Copyright (c) motion10. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
 
using System.Globalization;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
 
namespace Motion10.SharePoint2007 {
    public class DownloadAsZipAction : MenuItemTemplate {
        /// <summary>
        /// Initializes a new instance of the <see cref="DownloadViewAsZipAction"/> class.
        /// </summary>
        public DownloadAsZipAction()
            : base("Download as Zip", "/_layouts/images/ICZIP.GIF") {
            base.Description = "Download selected files or complete view if no items selected.";
        }
 
        /// <summary>
        /// Sends the content of the control to the specified <see cref="T:System.Web.UI.HtmlTextWriter"></see> object, which writes the content that is rendered on the client.
        /// </summary>
        /// <param name="output">The HtmlTextWriter object that receives the server control content.</param>
        [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel=true)]
        protected override void Render(System.Web.UI.HtmlTextWriter output) {
            ListViewWebPart listViewWebPart = FindListView(this.Parent);
            if (listViewWebPart == null) {
                this.Visible = false;
            }
 
            if (this.Visible) {
                string navigateUrl = string.Format(CultureInfo.InvariantCulture,
                                                   "{0}/_layouts/DownloadAsZip.ashx?List={1}&View={2}&Item=",
                                                   SPContext.Current.Web.Url,
                                                   listViewWebPart.ListName,
                                                   listViewWebPart.ViewGuid);
 
                string clientClick = string.Format(CultureInfo.InvariantCulture,
                                                   "window.location = '{0}' + GetSelectedItemsString('WebPart{1}')",
                                                   navigateUrl,
                                                   listViewWebPart.Qualifier);
 
                this.ClientOnClickScript = clientClick;
            }
 
            base.Render(output);
        }
 
        protected ListViewWebPart FindListView(Control parent) {
            ListViewWebPart retVal = parent as ListViewWebPart;
            if (retVal != null) {
                return retVal;
            }
 
            if (parent.Parent == null) return null;
 
            return FindListView(parent.Parent);
        }
    }
}

The code is pretty straightforward. We create a class that inherits the MenuItemTemplate class and we change the ClientOnClickScript property in the render method. What the result of this is, is that client will be redirected to the DownloadAsZip.ashx with the selected items in the querystring. The javascript is explained in one of the previous posts.

To add this button to the ListView we need to adjust our elements.xml a little. We actually add two more CustomAction elements in there.

<CustomAction
  Id="{DE394AD0-0A8E-4e5c-B246-A498BA2A7FB2}"
  Title="Download as Zip"
  RegistrationType="List"
  RegistrationId="101"
  Location="Microsoft.SharePoint.StandardMenu"
  GroupId="ActionsMenu"
  ControlAssembly="SharePointSolutionPack, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4a7cd02bdf107f7a"
  ControlClass="Motion10.SharePoint2007.DownloadAsZipAction">
</CustomAction>
<CustomAction
  Id="{CB4BE13C-C095-4a02-B875-787325045759}"
  Title="Enable item selection"
  RegistrationType="List"
  RegistrationId="101"
  Location="Microsoft.SharePoint.StandardMenu"
  GroupId="ActionsMenu"
  ControlAssembly="SharePointSolutionPack, Version=1.0.0.0, Culture=neutral, PublicKeyToken=4a7cd02bdf107f7a"
  ControlClass="Motion10.SharePoint2007.SelectItemsAction">
</CustomAction>

The second one is to add the ‘Enable item selection’ button and the first one to add the ‘Download as Zip’ button. Pay attention to the RegistrationId again. We add this button only to lists that inherit from the Document Library.

Wrapping it up

Well if you read all of the posts you’ve noticed that this is a pretty complex feature. We have a dependency on the jQuery feature. A lot of JavaScript. A custom HttpHandler etc. etc.

If you don’t know how to create solution packages yourself. Or if you don’t have the time to read all posts and create your own packages you can download the motion10 SharePoint Solution Pack.  I’ve updated the Share Point Solution Pack to contain all these and and some more features.

!Please be smart and test the solution package in a test environment!

Cheers and have fun,

Wes

More Posts