Tuesday, January 8, 2008

Working with sub folders in list

Hi all,

As you all know, in 2007 SharePoint introduced a new feature to lists - creating items in sub folders. But apparently the API was not modified in an easy way to support working with this feature...

In my last project I had to create sub-folders in lists and list items in these folders from code, and found that it is not so simple.

We are doing a rating solution for SharePoint items (coming soon on our web site, for more information contact sales@kwizcom.com), and wanted to create a new "item rating" list to store all ratings for all items on the same site.
For performence issues we wanted to create a sub folder for each list in the site and a second level folder for each item and create all ratings and comments in that folder.

The outcome of that project was 3 utilities methods that manages all that I need for working with folders and I thought it would be nice to publish them here - mainly because when I googled for it I didn’t find any good posts for that.

Here is how to use the utilities methods in your project:

SPList list = GetOrCreateList(web);//create your own...
//Create subfolder named "first level"
SPListItem folder = GetOrCreateFolderInList(list, list.RootFolder, "first level");
//Create subfolder named "second level"
folder = GetOrCreateFolderInList(list, folder.Folder, "second level");
//Create item in "second level" folder
SPListItem item = AddListItemInFolder(folder);
//Update meta data of new item
item["Rating"] = 5;
item["Comments"] = "";
item["ListID"] = list.ID.ToString("N");
item["ItemID"] = "ITEM_ID";
item["UserName"] = "shai...";
item.Update();


Here is the code for the utilities:

private SPListItem AddListItemInFolder(SPListItem parentFolder)
{
return parentFolder.ListItems.Add(parentFolder.Folder.ServerRelativeUrl, SPFileSystemObjectType.File);
}
private SPListItem GetOrCreateFolderInList(SPList parentList, SPFolder parentFolder, string folderName)
{
folderName = folderName.ToLower();
string parentFolderUrl = parentFolder == null ? "":parentFolder.ServerRelativeUrl.ToLower();
//Look in existing folders
foreach (SPListItem f in parentList.Folders)
if (f.Folder.ServerRelativeUrl.ToLower() == parentFolderUrl + "/" + folderName)
return f;//Found! return it!

//not exists - create
SPListItem folder = parentList.Items.Add(parentFolderUrl, SPFileSystemObjectType.Folder, folderName);
folder.Update();
return folder;
}


Well, hope this helps you - it sure did help me :)
Shai Petel,

Tuesday, December 18, 2007

Data View Web Part - Add Link to view properties form

Well... this must be the shortest tip I evet posted, and tell you the truth - its for me more than it is for you.

Every time I add a data view web part (DVWP) using the SharePoint Designer I have to look for how to add a link to the view item properties window.

Well, in case you didnt know this - DVWP has some properties that allow to build that string dynamically according to the current list. This is only done if you add a "List View" web part, and use the SharePoint Designer option to convert it to data view (menu: convert to XSLT data view, what we call DVWP).


Well, the solution is very easy, inside a <a>tag surrounding the @Title value, just add this tokens:
href="{$URL_Display}?ID={@ID}"
and thats it!



So, now I have where to get it from when I need it :) and maybe you will find it usefull as well...

Tuesday, December 11, 2007

Using InfoPath Forms Server with anonymous users

For so long I have been trying to convince my customers that the right combination of InfoPath, MOSS and workflow can solve 70% of their day to day business needs.

Well, guess what – I finally succeeded.

Only to learn that by default – forms server does not allow anonymous users to create new forms.

Well, my customer wanted to implement a “contact us” and “register to…” forms on his WCM MOSS internet site that will (of course) be published on the internet and allow any potential customer to fill in these forms with no need for logging in or registering for their site.

So, the solution for this consisted of 2 major steps.

Step 1 – defining out SharePoint site to use forms authentication provider.



I extended my AD web application (i.e. http://moss.kwizcom.com ) to a new web application (i.e. http://forms.kwizcom.com ) that uses forms authentication – this way I could create a simple user that has no privileges at all except to create items in the forms library (no edit / delete as well).

Step 2 – setting up a default logon user for anonymous users.



After step 1, all I had to do is to create a forms authentication user named: Internet User and give him write access to the forms library. Now, I added some code to auto login with that user when anyone browses to this web application http://forms.kwizcom.com.

For more information about completing step 1 you can see may blogs articles – simply google it.

I like Andrew connell’s one here: http://www.andrewconnell.com/blog/articles/HowToConfigPublishingSiteWithDualAuthProvidersAndAnonAccess.aspx

After you have forms authentication enabled on your second web application, the solution is rather easy.
  1. Create an InfoPath form, save it and publish it to a document library on your SharePoint server
  2. Create a new permission level on your site collection for “Add Only Read Only Permission”
    1. Go to Site Settings – top level site settings
    2. Click on advanced permissions
    3. On the “Settings” menu click on “Permission Levels”
    4. Add a new permission level named “Add Only Read Only Permission”
    5. Select only the “Add Items” check box (others will be auto selected – leave them)
    6. Click “Create”
  3. Create a new forms user named: Internet User
    1. Use the ASP.Net application to create a new user as explained in the Andrew Connell blog post above
  4. Give Internet User “Add Only Read Only” permission on the published form library
    1. Browse to the document library
    2. On the “Settings“ menu click “X Library Settings”
    3. Click on “permissions for this document library”
    4. If you don’t see the “new” menu item – you will have to break permissions for this library by clicking “Actions” and then “Edit Permissions”
    5. Click “New”, select Internet User give user permission directly to “Add Only Read Only Permission” permission level.
  5. Set up auto login for Internet User
    1. Go to the http://forms.kwizcom.com web root folder (by default: under c:\inetpub\wwwroot\wss\virtualdirectories\*
    2. Locate the global.asax file, back it up and open it in notepad
    3. Add this lines to the file to enable auto login as Internet User,
      replace [password] with the password you given the user.
      <script runat="server">
      public void FormsAuthentication_OnAuthenticate(object sender, FormsAuthenticationEventArgs args)
      {
      if (Membership.ValidateUser("Inernet User", "[password]"))
      {
      FormsAuthentication.SetAuthCookie("Inernet User", true);
      }
      }
      </script><.div>
    4. Save the file and close it.
Now we have to prepare the link for filling out this form using the browser.
To do so you will need a client PC that does not have InfoPath installed, browse to http://moss.kwizcom.com to the forms library, and click “New” on the forms library.
The forms server will open a browser based form for you to fill in.
Copy the URL of the create form page and replace http://moss.kwizcom.com with http://forms.kwizcom.com , replace moss with forms anywhere you see it in the query string as well, except for the “Source=” query string parameter.

That’s it! Simply put that URL at your site where you want users to create forms from and you are done!

Note: you might want to prevent user from browsing to http://forms.kwizcom.com and redirect them to the http://moss.kwizcom.com. This can be done in several ways. For demo purposes you could add this javascript to your master pages to make them do the redirect for you:

<script>
if(window.location.href.toLowerCase().slice(0,12) == “http://forms”)
window.location.href = window.location.href.toLowerCase().replace(“http://forms”, “http://moss”)
</script>