Friday, November 14, 2008

Storing SPListItem in SPFolder

We have had a need to store SPListItems into a folder structure in a SPList (preferably without the user having to navigate to the folder and select 'New Item'). The folder structure we required is a top level of year and then a month folder.

Much research on the web was about having a list event handler that moves the list item to the desired location. Move however for a list item (not document) is only possible by creating a new item in the desired location, copying all field values and then deleting the original item. I thought this was ridiculous and that there must be a better way.

I decided to attack the problem from the other end and change the folder location before the list item is saved.

To do this I created a simple web part and placed it in the "NewForm.aspx" of the list. The web part checks the current folder (stored as "RootFolder" in query string), compares it to the expected location and if needed redirects to the same page with the corrected RootFolder.

The code below demonstrates:

(code for DoesFolderExist/CreateFolder can be found in previous article)


protected override void Render(HtmlTextWriter writer)

{

    base.Render(writer);

 

    SPList list = SPContext.Current.Web.Lists["ListName"];

 

    DateTime today = DateTime.Today;

 

    string expectedFolderPath = string.Format("{0}/{1}", today.Year, today.Month);

 

    string currentRootFolder = Page.Request.QueryString["RootFolder"];

    string expectedRootFolder = string.Format("{0}/{1}" , list.RootFolder.ServerRelativeUrl, expectedFolderPath);

 

    if (currentRootFolder != expectedRootFolder)

    {

        if (!DoesFolderExist(list, expectedFolderPath))

            CreateFolder(list, expectedFolderPath);

 

        Page.Response.Redirect(HttpUtility.HtmlEncode(string.Format("{0}/{1}?RootFolder={2}", list.ParentWeb.Url, list.Forms[PAGETYPE.PAGE_NEWFORM].Url, expectedRootFolder)));

    }

}

No comments: