Wednesday, October 13, 2010

SharePoint 2010 Drop Off Library !!!!

Another new feature you may have seen in SharePoint 2010 is the drop folder this is basically a way to set up one folder for users to upload files to and it will automatically route the files to the appropriate locations that you have previously setup.

So how do we get this to work? Well it does need some setting up and the routing rules do need some configuring but well worth the effort. First of all from your site go to

Site Actions -> Site Settings -> Manage Site Features and activate the “Content Organizer” feature. After this is activated there are two new items under the site administration section these are “Content Organizer Settings” and “Content Organizer Rules”


SharePoint 2010 Drop Off Library

Friday, September 3, 2010

SharePoint Custom Search Results Page - (Search Documents)

The built-in Windows SharePoint Services search results page (SearchResults.aspx) is rather limited in the document metadata that it displays in the result list. Furthermore, the format of the list is not what every client wants. My client wanted lots of document metadata displayed in a "table", and only wanted results from a single document library in the site. So, I created a custom search page to implement this functionality. To display the results, I used a DataGrid, but you could use any formatting you want.

This example shows how to create a custom search results page that will display any metadata available for a document. It is totally flexible in that it gets the metadata fields to display from a client-configured document library view. This means that if the client decides s/he wants more (or fewer) categories to display, or wants to change their order, the results page will automatically adjust when the document library view is changed. This solution uses a simple Content Editor web part with some client-side HTML and JavaScript to invoke the search. This leaves the original search box and search results page for normal site-wide searches (which includes multiple libraries and lists).

Summary of Features:
The search form is implemented as a simple Content Editor web part, containing only client-side HTML and JavaScript.
The search itself is implemented by creating a custom search results page, based on the pre-existing SearchResults.aspx, which uses the built-in SharePoint search functionality and manipulates the results to display more metadata than the standard search results page.
The metadata to display, and the order to display it in, can be changed using a standard SharePoint view on the document library to be searched.
The search results page provides a form field for immediate re-search without having to return to the originating page.
Results can be sorted by clicking on any column header.
Clicking on the document title itself (or the icon) takes the user to the document�s property page.
Built-in search functionality is not affected.
Download SharePoint Custom Search Results Page - (Search Documents)

Tuesday, July 20, 2010

Creating Custom Tool Part !

Hi All,

First let me just highlight you what do we mean by toolpart. When you create your webpart and place it on your page and when you modify the webpart, at the time what appears right hand side is a panel and if you want to place any specific control there as a property, then we can create toolpart for the webpart.

Here we go with the example. Let’s say that we already have one web part which inherits from Microsoft. Sharepoint.WebpartPages.Webpart

So all you need to do is this.

Step 1: First you need to define the property. At the time of defining the property, do keep in mind what kind of a property is that, is it personal property (per user based) or shared property (common for every user)


Check out its two attributes named WebPartStorage and PersonalizationScope which will tell you the scope (personal or shared)

Let’s say we define one property called CustomerName

private string strCustomerName = string.Empty;

[Browsable(false),//Display the property in property pane
Category("CustomToolPart"),//Create a Customer Details category in property pane
DefaultValue(""),//Assign a default value
WebPartStorage(Storage.Personal),//Make available in both personal and shared mode
Personalizable(PersonalizationScope.User),
FriendlyName("Customer Name"),//The caption display in property pane
Description("The name of the customer")]//The tool tip
public string CustomerName
{

get
{
return strCustomerName;
}
set
{
strCustomerName = value;
}
}


Just like this, as many properties that you want to define, define them in the code of your webpart class.


Now is the time of override one method which is GetToolParts(), but before proceeding here let us understand these two classes.

(1) WebPartToolPart – It actually represents a tool part that can be used to show and modify Web Part base class properties.

And

(2) CustomPropertyToolPart – Same as above, the only difference is that it is used to show and modify the custom propoerties that we have defined in the webpart class that are not the webpart base class propoerties.

So coming back to our GetToolParts method. Here toolpartclass is class that we are soon going to create.


public override ToolPart[] GetToolParts()
{
ToolPart[] toolparts = new ToolPart[3];

WebPartToolPart wptp = new WebPartToolPart();

CustomPropertyToolPart custom = new CustomPropertyToolPart();

toolparts[0] = wptp;

toolparts[1] = custom;

toolparts[2] = new {toolpartclass}

return toolparts;
}



Actually this method returns you the instance of the different toolparts that comes right hand side when you modify the webpart.

Here as you can see, we have got webparttoolpart and also custompropoertytoolpart along with the toolpart class that soon we are going to develop.

Ok, let’s develop and create ToolPart class which will have RenderToolPart and ApplyChanges method.

Create a class which inherits from Microsoft.Sharepoint.WebpartPages.ToolPart.

Declare a variable which will be the name of the control renders in toolpane

private string strHTMLinputControlName = "Mycontrol";

Write down the RenderToolPart method which is vey important.

protected override void RenderToolPart(HtmlTextWriter output)

{

// Establish a reference to the Web Part.

// CustomWebPart is the web part class name.

{webpartclassname} customWebPart =

(webpartclassname)this.ParentToolPane.SelectedWebPart;

//Create the input control

output.Write("Enter the customer name: ");

output.Write("<input name= '" + strHTMLinputControlName);

output.Write("' type='text' value='" +

SPEncode.HtmlEncode(customWebPart.CustomerName) + "'><br>");

}


Here if you observe, we have first taken the reference of the webpart class for which we are creating this toolpart. So parentToolPane.SelectedWebPart will be the webpart for which we are creating toolPart.

Now write down ApplyChanges method which will be called when we press OK or Apply after applying property in propoertypane of webpart.

public override void ApplyChanges()
{

// apply property values here

//Get a reference to the web part class

{webpartclassname} cw1 =

(webpartclassname)this.ParentToolPane.SelectedWebPart;

//Pass the custom text to web part custom property

cw1.CustomerName = Page.Request.Form[strHTMLinputControlName];

}


Here as you can see, we have gain taken reference of webpart class for which we are creating propoerty with custom toolpane. And then take the entered data with request.form and passing control’s name and setting to the propoerty defined in the webpart class which is CustomerName in our case.

That’s it. You are done with your job. All you have to do is go to your webpart page. Edit the webpart in pursonalize this page mode as because we have defined our propoerty as per user basis, edit webpart, click on modify my webpart and then as you can see for each different user will be able to set their own customerName.

And then simple, refer this.CustomerName as part of code in your webpart class, per user bases you will get the values set by individual user.

Have a fun. Try to explore toolpart class more.

Thank you.

Creating and Working with SharePoint Timer Job Definitions !

Hi All,

Many times we require creating a timer job definition because of requirement logic. Let’s say, we have some requirement something like whenever list gets added to the site, site administrator should get email saying that this list is being added by so and so person at this time.

Second example, you are supposed to write a job which starts the workflow every night for an approval process of some data calculations.

Now we do not have anything like ListAdding and ListAdded event that gives the answer of our question or any other event that solves some requirement like second example.

In these cases, we can create custom timer job and specify when to run and what to do when it runs.

So let us go ahead and create a custom timer job.

For this, I suggest creating a feature class which installs the job definition when activated and removes the job definition when feature is deactivated or other way is to go to timer job definitions under Operations in central administration and disable that specific job definition.

Before starting up the example, I also would like to explain you few classes for scheduling. Depending upon the schedule that you want to set, you need to take the classes. For example we have SPWeeklySchedule, SPDailySchedule, SPMonthlySchedule, SPYearlySchedule, SPHourlySchedule, SPMinuteSchedule.

You must have got the idea by the name of these classes when to use them. If you want to run your job every hour, you have SPHourlySchedule; if you want it to run every minute then you have SPMinuteSchedule. You can get the idea about the properties that needs to be set when using respective classes from searching MSDN.

Here I am taking an example of SPMinuteSchedule to explain you the example. Do keep in mind that different classes have different properties to be set.

First thing, create a Feature class.

namespace xyz
{
public class ListAddedFeature : SPFeatureReceiver
{
const string LIST_ADDED_JOB_NAME = "ListJobNameAddingCheck";

public override void FeatureInstalled (SPFeatureReceiverProperties properties) {
}

public override void FeatureUninstalling (SPFeatureReceiverProperties properties) {
}

public override void FeatureActivated (SPFeatureReceiverProperties properties) {
SPSite site = properties.Feature.Parent as SPSite;

// make sure the job isn't already registered
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) {
if (job.Name == LIST_ADDED_JOB_NAME)
job.Delete();
}

// install the job
ListAddingLatestJob taskLoggerJob =new ListAddingLatestJob(LIST_ADDED_JOB_NAME, site.WebApplication);

SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 59;
schedule.Interval = 5;
taskLoggerJob.Schedule = schedule;

taskLoggerJob.Update();
}

public override void FeatureDeactivating (SPFeatureReceiverProperties properties) {
SPSite site = properties.Feature.Parent as SPSite;

// delete the job
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) {
if (job.Name == LIST_ADDED_JOB_NAME)
job.Delete();
}
}

}
}



This gives you an idea that when feature will be activated at that time job will be scheduled, if exists then removed and then scheduled and at the time of deactivating job will be removed. When you will activate the feature you will find the Job name in the Timer Job Definitions in the operations section of central administration under global configuration section and you can also see the timer job status but you won’t find your custom timer job there untill it executes atleast once. This will run every 5 minutes.

Here I also would like to share is what is the significance of BeginSecond and EndSecond and any such propoerty for Begin and End for any above class is that timer job starts at any random time between sub specified time durations. This is because if you have many timer jobs running at the same time, then it could put a heavy load on server.

Here is actual job definition class.

namespace xyz
{
public class ListAddingLatestJob : SPJobDefinition
{


public ListAddingLatestJob()
: base(){
}


public ListAddingLatestJob (string jobName, SPService service, SPServer server, SPJobLockType targetType)
: base (jobName, service, server, targetType) {
}

public ListAddingLatestJob(string jobName, SPWebApplication webApplication)
: base (jobName, webApplication, null, SPJobLockType.ContentDatabase) {
this.Title = "ListAdding Check";
}


public override void Execute (Guid contentDbId) {
// get a reference to the current site collection's content database

SPWebApplication webApplication = this.Parent as SPWebApplication;

SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];

SPWeb objWeb = contentDb.Sites[0].RootWeb;

DateTime objTISiteCreationtime = objWeb.Created;

SPList taskList = contentDb.Sites[0].RootWeb.Lists["Tasks"];


SPQuery objQuery = new SPQuery();

objQuery.Query = "<Where><Gt><FieldRef Name=\"ID\"/><Value Type=\"Counter\">0</Value></Gt></Where>";

SPListItemCollection objCollection = taskList.GetItems(objQuery);

DataTable dtAllLists = objCollection.GetDataTable();

ArrayList objArrayList = new ArrayList();

if (dtAllLists != null)
{
if (dtAllLists.Rows.Count > 0)
{

for (int iCnt = 0; iCnt <= dtAllLists.Rows.Count - 1; iCnt++)
{

objArrayList.Add(Convert.ToString(dtAllLists.Rows[iCnt]["Title"]));
}
}
}


for (int iCnt = 0; iCnt <= objWeb.Lists.Count - 1; iCnt++)
{
if (!objArrayList.Contains(objWeb.Lists[iCnt].Title))
{
if (objWeb.Lists[iCnt].Created.ToShortDateString()
!= objTISiteCreationtime.ToShortDateString())
{

SPListItem newTask = taskList.Items.Add();

newTask["Title"] = objWeb.Lists[iCnt].Title;

newTask.Update();
//Write a logic to send a mail to admin

}
}
}


}

}
}


Do not go deep into the logic, as this is just to give an idea about the creation of timer job and along with that simple logic which checks for the lists created by default at the time of site creation which will have the created time same as time created for site.

What I am doing here is first I am storing List Names in the Tasks List (Just to demonstrate you, you can change the logic suiting to your need). I get all items from the tasks list and compare stored Title (List Name) with the each list name of the site, if not there that means it is newly created, send mail to admin and then add the list name again to tasks list title column. So this will keep on working and every five mintes, it will keep checking if newly list has been added or what and sends mail.

Please note that logic is not perfact, just to demonstrate you and give you an idear about Timer job definition and at the same time idea about how to implement List added logic. You can share the best idea with us.

IMP : How to debug the timer job definitions.

Other very important thing is debugging the timer job definitions. Debugging timer job definition is something different because its not about attaching w3wp process because this doesn’t run under web. So we do have other process here to attach to get this thing debug. Name of the process is OWStimer.exe. When you attach this process, then just wait for your timer to get to the right defined time by you and then it will automatically come for debugging. Means if you have set it to 2 minutes, then attach the OWStimer.exe process and just wait for 2 minutes. Every 2 minutes you will get the breakpoint hitting the location.

Ok, one more thing. If you have observed the Timer job definition in central administration, then it gives you an option to disable the job definition but it doesn’t allow to execute it at force.

One way to go about this is to use the stsadm –o execadmsvcjobs but the problem with this is it will execute all the administrative timer jobs without waiting for any job to run in schedule because it doesn’t take any parameter.

So solution is again code. Here is that one liner code that does stuff for us.

foreach (SPJobDefinition job in site.WebApplication.JobDefinitions) {
if (job.Name == LIST_ADDED_JOB_NAME)
job.Execute(site.WebApplication.ContentDatabases[0]);
}


That;s it. Your job is done.

Understanding Feature activation dependencies !

Hi All,

When you create the feature, it can also include the dependencies. Let’s say, we have one feature that is dependent on the other feature, that means when we activate one feature, it actually requires the other feature already been activated, at that time we can use this feature dependencies.

A very good example of this is TeamCollab feature which activates many other features automatically. It creates several list templates and makes it available for the site.

Let me give you a very simple example of Feature Dependencies.

<Feature
Id={GUID}
Title={title}
Description={Description}
Version={version}
Hidden={value}
Scope={value}
xmlns={namespace} />

<ActivationDependencies>

<ActivationDependency FeatureId = {dependent Feature GUID}/>

</ActivationDependencies>


That means the feature inside the ActivationDependency must be activated before the main feature gets activated.

If the main feature is A and inside ActivationDependency we write feature B, then activating Feature A first activates feature B and then activates feature A.

Note that Feature B must be installed first at specific scope.

Other very important thing to note here is you must have to define feature B (Feature that goes inside ActivationDependency) as Hidden, otherwise SharePoint will throw error saying that the dependant feature is not enabled.

That's it. your job is done.

Getting all documents in document library inside all folders !

Hi All,

Many times we require getting all documents in the entire document library including sub folders. For this we need to use the ViewAttributes property on SPQuery object and set it to specify Scope=\"Recursive\

If we don’t do this, then result we will get it all documents from the top folder only.

Here is a simple way, we will achieve this.

SPList objList = objWeb.Lists["{name of the doc lib}"];

SPView objView = objList.Views["name of the view"];

SPQuery objQuery = new SPQuery(objView);

objQuery.ViewAttributes = "Scope=\"Recursive\"";

SPListItemCollection objItemColl = objList.GetItems(objQuery);


Sometimes we may require returning the result from specific folder inside the document library.

At this time, we need to use SPFolder class and set the SPQuery object’s Folder property to the object of SPFolder.

Here is a way.

SPFolder objFolder = objList.RootFolder.SubFolders["name of the folder"];
objQuery.Folder = objFolder
That is it. Your job is done.

Changing redirection in SharePoint with HttpModule and HttpHandler !

Hi all,

SharePoint is maintaining some redirection by it’s on like error page, by clicking on user or group it will redirect to profile page and so many other…

In one of our requirement we have to implement custom profile page and custom error page.

So for this we need to over ride default SharePoint navigation.

And that can be implemented using HttpModule and HttpHandler.

To know the concept of HttpModule and HttpHander here is great article from Gustavo Velez

So here we go for changing Error page (check comments between the code for understanding)

class RedirectErrorModule : IHttpModule
{

//Custom error page relative URL
const string errorUrl = "/_layouts/CustomForder/CustomError.aspx";

// implement dispose method to dispose used object
public void Dispose()
{
//dispose you objects
}

public void Init(HttpApplication context)
{
//Define event for application error so that you can override.
context.Error += new EventHandler(context_Error);
}

//implement error event
void context_Error(object sender, EventArgs e)
{
string strURL = string.Empty;

//Current site URL
string strSiteURL = SPContext.Current.Site.Url;

//Current web url
string strWebURL = SPContext.Current.Web.Url;

//Clearing context error
HttpContext.Current.Server.ClearError();

//Clearing the response
HttpContext.Current.Response.Clear();

//redirecting to our custom error page.
HttpContext.Current.Response.Redirect(strWebURL + errorUrl, false);
}

}


After doing this we need to add entry in web.config for the same.

Enter following tag in <httpModules> section of your web.config
<add name="CustomHttpModule" type="<<Full assembly name with class>>" />

Check syntax from existing tags from web.config.

The same way we can implement any redirection with the use of end request Event.
public void Init(HttpApplication context)
{
//end request handler
context.EndRequest += new EventHandler(context_EndRequest);
}

//End request implementation
void context_EndRequest(object sender, EventArgs e)
{
HttpApplication httpApp = sender as HttpApplication;
HttpContext context = httpApp.Context;
string httpUrl = context.Request.Url.ToString();
string strWebURL = string.Empty;
string struserID = string.Empty;
//compare your URL and redirect it to custom one
// this is example to redirecting userdisp page (profile page) to custom page.
if (httpUrl.ToLower().Contains("/_layouts/userdisp.aspx"))
{

//implement business logic and generate url if needed
HttpContext.Current.Server.ClearError();
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Redirect(<<Custom URL>>);

}
}


And same can be incorporated in one class no need to create another one.

And remember in web.config enter your module at the end after all SharePoint’s event handler so it will not create any problem. There is not at all problem if you write it before SharePoint’s but better to play safe :)

Hiding field in SharePoint through JavaScript !

Hi All,

Many times we require to hide specific field in new form, disp form and edit form. This time we will do it with the help of javascript. We can do the same thing with the help of SharePoint API. However we will cover here that how to achieve the same with the help of JavaScript.

Let us go to calendar and click on new. You will now be on Newform.aspx. We can see here one field named “WorkSpace”. If we don’t want user to create any workspace here, then we can hide this field with the help of JavaScript code.



To hide a specific field, insert one content editor web part on the page and then just copy and paste the following code. Insert this web part below the new form web part.

<script type="text/javascript">
function HideField(title){
var header_h3=document.getElementsByTagName("h3") ;

for(var i = 0; i <header_h3.length; i++)
{
var el = header_h3[i];
var foundField ;
if(el.className=="ms-standardheader")
{
for(var j=0; j<el.childNodes.length; j++)
{
if(el.childNodes[j].innerHTML == title || el.childNodes[j].nodeValue == title)
{
var elRow = el.parentNode.parentNode ;
elRow.style.display = "none"; //and hide the row
foundField = true ;
break;
}
}
}
if(foundField)
break ;
}
}

HideField("Workspace");

</script>


After you’ve inserted this code, just look at the result shown below.



That’s it. Your job is done. You can apply the same code in disp and edit form as well.

Hide Content Place Holder Programmatically !

I was working on replacing a control from the master page by a custom web part. Initially i commented everything inside the content place holder and added my web part. If you want to know how to add a web part in the master page, have a look at my previous post at :

http://www.sharepointkings.com/2009/09/add-web-part-inside-master-page-in-moss.html

Later on i moved the web part reference out of the content place holder and made the visible attribute of the content place holder to false.

But now the requirement is to dynamically turn it ON and OFF (i.e through code)

Lets follow the steps given below to achieve this:

1. Go to the page_load method of the web part.
2. Write the following lines of code.


if (!Page.IsPostBack)
{
ContentPlaceHolder contPlcHolder = (ContentPlaceHolder)Page.Master.FindControl("PlaceHolderGlobalNavigation");
contPlcHolder.Visible = false;

//Rest of the code

}


If there is any nested content place holder then append that number of FindControl("ControlName") to the above code where we are finding the control.

That's it. Save the code and deploy the latest web part code.

Add Web Part inside a Master Page in MOSS 2007 !

Imagine that you are designing a master page for your MOSS site and you have a requirement to have a functionality that is not possible out of the box. You brain storm on it and concludes that only custom web part can solve your problem.
But now your concern is how you can make this custom web part as part of your master page?
It’s easy! Just follow the steps given below to add a web part inside a master page.

1. Deploy the web part in your web application as you do normally.
2. Check whether the web part is showing up in the web part gallery.
3. Create a web part page by navigating to the site settings, create web part page.
4. Add your custom web part on the web part page.
5. Start SharePoint designer and open the newly created web part page.
6. You will now find two entries corresponding to the web part you added on the page
i. In the page declaration you will find a entry which looks something like this:


<%@ Register TagPrefix="WpNs0" Namespace="MyNamespace.MyClass" Assembly=" MyNamespace.MyClass, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"%>

ii. Click on the web part section in the page and you will see an entry like this:


<WpNs0:WebPartName runat="server" ID="g_34cdbb90_38c6_4561_9182_8fbc0d2423a6" ExportMode="All" Title="WebPartTitle" __MarkupType ……………..

7. Copy these entries in separate notepad, and close the page opened in the SharePoint designer.
8. Now open the master page in SharePoint designer and add the first entry in the declaration section and second entry at the place where you want to add the web part to.
9. Save the page, check in and publish it and that’s it. Your job is done.


Do let us know in case you are facing any issue following the steps mentioned.

Monday, July 19, 2010

Dynamic Connected Lookup For Sharepoint !

Project Description

A custom field control for WSS 3.0/MOSS 2007 to acces the list items easily .

This is one of my projects having a custom list which acces data :
DCLTEST.JPG
The custom field is ;
Spfield.JPG
SpField2.JPG
The Dynamic Connected Lookup is ;
DCL2.JPG
The Final is;
F.JPG


rafetcomu@gmail.com



Last edited Apr 18 at 12:10 PM by RafetCambaz, version 6

Download Dynamic Connected Lookup For Sharepoint !

Cross-site lookup in Sharepoint !

Project Description
This project creates a custom SharePoint lookup field that offers new functionalities to default SharePoint lookup field by allowing filters to be applied to retrieved data. Applied filters can be either dynamic CAML queries or pre-defined list views residing in source lists

Below is a few of the features offered by Filtered Lookup field over standard SharePoint Lookup field:
  • Cross-site lookup (all sites within same site collection)
  • Filter retrieved data using list views
  • Filter retrieved data using dynamic/ad-hoc CAML queries. This means you don't need to create a list view each time you want to apply a lookup filter to source data
  • Supports retrieving data recursively using either list views or dynamic queries
  • Supports MultiLookup with filtered data
  • Same look and feel as default SharePoint Lookup and MultiLookup (i.e. in list forms)

The project is packaged as a Windows installer using the SharePoint Solution installer; to install, simply run setup.exe.

Please do let me if you find any issues or bugs or useful enhancement that could be added

FieldTypeList.jpg

FieldProp_Q2.jpg

FieldProp_V.jpg
Download Cross-site lookup in Sharepoint
Download SharePoint Connected Lookup

Configuring the breadcrumb for pages in _layouts !

If you have ever added a page to the _layouts or _admin folders in SharePoint 2007 you may have wondered how to get the breadcrumb to appear at the top of the page. As with many things in MOSS they are using the standard ASP.Net 2.0 navigation features, in particular the sitemap.

To see how it’s done you can simply open the layouts.sitemap (or admin.sitemap) in the ‘_app_bin’ folder of a MOSS IIS site to see how the breadcrumb is built. By editing this file you can ensure your own pages have a breadcrumb and the navigation works.

Now, having done that the chances are that you are going to create a feature so that this page can be used on other sites or farms. Great, you can create a Solution Package and add a file to the LAYOUTS folder which has a specific naming convention – layouts.sitemap.???.xml – where ??? is the name of your feature (has to be unique). This will then get merged into layouts.sitemap when you create a new application.

This is where there appears to be a problem…existing sites will not get updated with your new entries. I have found no way of updating the existing layouts.sitemap (or admin.sitemap) for every server in a farm using the SharePoint API. This problem is compounded by the fact that the sitemap is copied when the IIS site is created and so each IIS site (zone) in a application has to be updated.  

Ideally you could update the layouts.sitemap when your feature gets activated on every server in the farm and for every IIS site within the site collection.

This is where the UpdateLayoutsSitemap class comes in. UpdateLayoutsSitemap gives this functionality by creating a SharePoint job which is executed by OWSTIMER. Updating the layouts.sitemap can be as easy as this…

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

    SPWeb oWeb = (SPWeb)properties.Feature.Parent;

 

    SPThings.UpdateLayoutsSitemap uls = new UpdateLayoutsSitemap(oWeb.Site.WebApplication);

    uls.AddEntry(“Our Settings”, “/_layouts/oursettings.aspx”, “/_layouts/settings.aspx”);

    uls.AddEntry(“Add New Thing”, “/_layouts/addnewthing.aspx”, “/_layouts/oursettings.aspx?List=1″, “List”);

    uls.SubmitJob();

}

This will cause two new entries to be added to the layouts.sitemap for the specified WebApplication. The second entry will be a child of the first. But wait, if you have gone to the trouble of creating your layouts.sitemap.???.xml file would it not be better to use that? Of course you can…just don’t forget to replace the ??? with your own unique name.

public override void FeatureActivated(SPFeatureReceiverProperties properties)

{

    SPWeb oWeb = (SPWeb)properties.Feature.Parent;

 

    SPThings.UpdateLayoutsSitemap uls = new UpdateLayoutsSitemap(oWeb.Site.WebApplication);

    uls.AddSitemap(“layouts.sitemap.???.xml”);

    uls.SubmitJob();

}

It should also be noted that you can update admin.sitemap as well by adding true to the constructor…

SPThings.UpdateLayoutsSitemap uls = new UpdateLayoutsSitemap(oWeb.Site.WebApplication, true);

UpdateLayoutsSitemap inherits from SPJobDefinition and works by keeping track of the entries and adding them on every server that executes the job. SPJobDefinition is a very helpful class in that it inherits from SPAutoSerializingObject and so can persist all the class members you specify when the job is submitted. This means that when your job executes it is in the same state as when it was submitted. To enable this functionality you need to add an attribute to your class members so that they are persisted

[Persisted]

private System.Collections.Generic.List<string[]> _entries;

If you find it useful feel free to use this class as you see fit.

 

Download UpdateLayoutsSitemap Class File

Sharepoint Access Checker Web Part !

Project Description

Quickly check what objects within a Sharepoint site hierarchy a user has access to.

The Access Checker Web Part is a Windows Sharepoint Services Web Part, for use within Windows Sharepoint Services v3 and Microsoft Office Sharepoint Server 2007, that displays a tree view showing permissions on objects for a user scoped to a Site hierarchy. It also has a second mode which will show the permission inheritance of objects within a Site hierarchy.

Access Checker.png

More specifically, The nodes within the tree are colour coded. If the user's permissions on the content match or exceed the level of access specified, the node is coloured green, red otherwise. Enabling a Site Administrator to determine what access a user has and to which content within a Site.

Background

Frequently I would receive emails from site administrators fed up with managing permissions for users. A common scenario would be that a user needed to be able to read all content within a site. For a site admin to be certain of this, they would need to visit each list and library permissions page and check that a) the list was inheriting permissions or b) the list has unique permissions and the user needs to be added directly. (Not to mention folder and list item permissions, but that's outside the scope of what this web part addresses!)

Expand this problem out to groups of sites and it gets really scary...

This Web Part hopes to solve this management issue for site administrators. The web part will confirm what permissions a user has to each list and site at a certain level in a Sharepoint hierarchy. It can also show the permission inheritance hierarchy for a better understanding of how permissions are setup.

I would like to get some feedback on its usefulness and if you have any suggestions on improving this web part i would like to hear about them.

Additional Features

- View Permission Inheritance on Sites and Lists. Useful for site administrators to understand how permissions are configured on their sites.
- Sharepoint Feature included in the Solution that adds two links to the Site Settings Page.

SiteSettings.gif

Check User Access - Page with embedded Access Checker, configured for User Access Mode
View Permission Inheritance - Page with embedded Access Checker, configured for Permissions Inheritance mode.

Limitations

- List Items are not displayed.
- Does not currently work with Forms Based Authentication.
Download Sharepoint Access Checker Web Part !

SharePoint Cascading Drop Down List (With Filter) Field Type !

SharePoint Cascading Drop Down List (With Filter) Field Type

Top 25 Downloads For SharePoint On Codeplex !

A little earlier I saw a fellow SharePoint Twitter user lamenting about a lack of built in SharePoint tools for pulling reports around permissions. I posted a note that there was a utility up on Codeplex for pulling those type of reports when I realized that there were many Codeplex projects for SharePoint than many are probably unaware of. Below you will find listed the top 25 most downloaded SharePoint projects on Codeplex. If you want a greater listing just head on over to www.codeplex.com and select the SharePoint tag cloud on the right hand side of the page.

WSPBuilder
SmartTools for SharePoint
MOSS Faceted Search
SharePoint Learning Kit
SmartPart for SharePoint
STSDEV: Simple Tools for SharePoint 2007 Development
Microsoft SQL Server Community Samples: Integration Services
SharePoint SmartTemplates for Visual Studio
Podcasting Kit for Sharepoint
SharePoint Manager 2007
Useful Sharepoint Designer Custom Workflow Activities
iLove SharePoint
ChartPart for SharePoint
SharePoint Forums
SharePoint SUSHI
SharePoint Content Deployment Wizard
SPSReport
RSS FeedReader
FAST ESP Web Parts for SharePoint Server 2007
SharePoint 2007 Test Data Population Tool

Sharepoint lookup with picker !

Project Description
Microsoft Sharepoint Server 2007 lookup control with element picker for custom list.
This control is useful if you need to choose lookup data from large lists. This control supports single and multi select mode.

adding.png

newitem.png

dialog.png

newitem2.png
Download Sharepoint lookup with picker

Thursday, July 15, 2010

Easily print SharePoint lists using your own template !

Recently I have really wanted to easily print some SharePoint lists, but I always had to open them in Excel, format the columns and then print...this takes time. I looked at  Ishai Sagi's solution, but it didn't really do what I wanted...I really wanted the ability to print directly from the browser using a variety of templates. This also coincided with Brent starting a new CodePlex project to easily add functionality to a SharePoint site without having to use features or solutions. Essentially the project provides functionality for people where no binaries or layouts and can be deployed, and so can be can be used by people on shared hosting. I had agreed to work with him on the project and so thought I could combine the two!

The plan

The idea I had was to add some menu items to the standard WSS menus using javascript and to do all formatting client side. Obviously I chose XML & XSLT to do this, mainly because the SharePoint web services return XML, but also because it makes creating new templates so easy.

How it works

The javascript adds menu items to both the 'Actions' menu of a list view and also the to drop-down menu of the list items within the view...how this is done I will leave for another post! In response to choosing print a new window is shown, the list is retrieved using web services and then transformed using XSLT. This is shown in a DHTML dialog from which you can print it, print preview it or select a different template. Templates are defined in a document library using XSLT and you can add as many as you like.

What does it look like

Here are some screen shots from my blog admin site...

image image image

In the last screenshot you see the print dialog displaying what is actually going to be printed shown. From here you can choose to print, print preview or change the template...

image

Samples

You can download some sample prints ...

Item print sample (.xps) 

List print sample (.xps)

These samples show the pretty basic templates which are included. However they are generated using XSLT and so you can easily create your own by uploading them to the document library.

Installation

The functionality is provided as a list template. You need to download the .stp from the CodePlex project site and then upload it as a new List Template...

image

Once uploaded you can create a new document library using the template...

image

The template contains all the files required for the feature and once created you should see the templates...

image

You can now add the following lines to your default.master for your site just above the </body>...

<link rel="stylesheet" href="/PrintTemplates/printwindow.css"/>
<script language="javascript" src="/PrintTemplates/printwindow.js"></script>
<script language="javascript" src="/PrintTemplates/PrintFunctions.js"></script>
<script>_tk_enablePrintFunctions("/", "PrintTemplates")</script>   

Change the 'PrintTemplates' to be the same as the name of your document library.

You should now be able to navigate to any list and print the items.

Problems

Currently the two main problems are that I have only tested it with IE7 (no VM with IE6) and I have to use an ActiveX browser object for the print preview. Therefore in order for the print preview to work your site needs to be in the 'Local Intranet'  zone, if not you will see the following error...F5 will return you to the list.

image

Try it out

Brent has created a demonstration of the functionality Sharepoint Templates site.

Visit the SharePoint templates project on CodePlex for more information

You can download the ZIP containing the required files here. These can be placed in any document library or on the file system...as long as you can reference them in the src= of your SCRIPT tag.

Sample CustomActions for SharePoint !

SharePoint gives a lot of opportunities to customize the user interface and add your own customizations. There are a lot of examples of modifying the 'EditControlBlock', the drop down actions list shown on list items in a list view, and adding custom functionality to the 'Actions' menu of the list view.

I thought I would add my own to the mix, with a couple of samples which I have found useful in testing recently. The sample project adds two items to a list view...one to the 'EditControlBlock', which allows you to make a copy of the selected list item and another which adds an items to the Actions menu, which allows you to delete all the items in the current list.

image image

Adding the items is done via a feature and some custom actions. The actions are just pointers to .aspx pages in the _layouts folder and these pages actually perform the copying and deletion of SPListItems.

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

    <CustomAction

        Id="TheKid.DuplicateListItem"

        Location="EditControlBlock"

        Title="Copy Item..."

        RegistrationType="ContentType"

        RegistrationId="0x01">

        <UrlAction Url="~site/_layouts/TheKidListActions/CopyListItem.aspx?List={ListId}&amp;ID={ItemId}"/>  

    </CustomAction>

    <CustomAction

        Id="TheKid.ClearListItems"

        Location="Microsoft.SharePoint.StandardMenu"

        GroupId="ActionsMenu"

        Title="Delete All Items"

        RegistrationType="List"

        Sequence="10">

        <UrlAction Url="~site/_layouts/TheKidListActions/ClearList.aspx?List={ListId}"/>

    </CustomAction>

</Elements>

Note the query string parameters which have tokens representing various values you may need to use in your .aspx page. Here I use ListId and ItemID...the other two possibilities are ItemUrl and SiteUrl.

It is also worth noting the RegistrationType of the copy item CustomAction. This you can see is registering itself by content type and is using a RegistrationId of 0x01. This will register it for all lists in SharePoint. For more details of how SharePoint decides which items appear in the EditControlBlock you should have a look at the CORE.JS file in SharePoint. The CORE.JS file contains a function called InsertFeatureMenuItems which decides which items will be displayed in the menu for each item in the list.

The functionality for the two actions are completely contained within the .aspx pages and the project contains no DLLs and only installs the .aspx pages. To modify the functionality simply open the .aspx and change the code.

You can also use code to create the Custom Action URL.

You can download the WSP to install, or you can download the full source for the project.

UPDATE: I have another article which shows how to use code to achieve similar results.

Wednesday, July 14, 2010

Configuring Reporting Services 2008 R2 in SharePoint 2010 Integrated Mode – Part II

If you need to create an extremely user-friendly environment for Reporting Services 2008 R2, SharePoint 2010 Integrated Mode is the best solution. Configuring Reporting Services 2008 R2 in SharePoint 2010 Integrated Mode – Part 1 explains the initial configuration up to SharePoint integration. This post discusses creating a web site for Reporting Services with relevant libraries and content types, finally publishing reporting from BIDS.

Let’s start creating a Web Application. Go to SharePoint Central Administration and click Manage Web Applications under Application Management. Once Application Management is open, click on New to create a new web application.
newwebapp

Some of the attributed in New Web Application Form as as follows;

  • Authentication
    Select Classic Mode Authentication
  • IIS Web Site settings
    Select Create a new IIS web site option. I have named it as Report Server – 10005 and set the port as 10005.
  • Security Configuration
    Leave default values
  • Public URL
    In my case, URL is http://DP03:10005
  • Application Pool
    Make sure Create new application pool is selected. I have named it as ReportServer – 10005.
  • Database Name and Authentication
    Set the SQL Server name for Database Server. I have named the database as WSS_Content_ReportServer_10005.

webapp

Click OK to save setting. Once the process is completed, Application Created windows is appeared. Click OK to continue. New web application will be listed in Web Application window.
webapp2 
Next step is creating a site collection. Go back to Central Administration and click create site collections under Application Management. This opens Create Site Collection window. Let’s ceate one;

  • Make sure that correct web application is selected (In my case, it is http://DP03:10005/.
  • Add Title as Report Server.
  • Let’s use the root for the Web Site Address. Do not select sites from the drop-down. Leave it blank.
  • Select the Template as Team Site.
  • Set both Primary Site Collection Administrator and Secondary Site Collection Administrator. Since I have everything in one machine, I set both as DP03\Administrator;.
  • Click OK to create the site.
    sitecoll

Once done, a message will be appeared saying Top-Level Site Successfully Created. Click on the link to go the site (In my case, link is http://dp03:10005). This is what I see;
site

Site needs libraries for holding reports and connections. Let’s create two libraries for the site.

  • Click on Libraries link in left pane. It lists all document libraries available.
  • Click the button Create for creating a new library.
  • Select Document Library and Set the name as Reports.
    lib1
  • Click Create for creating the library. Once the library is open, click on Library Settings for adding content types.
     lib2
  • When Library Settings is open, library related things such as General Settings, Columns, and Views are shown. By default, it does not show Content Type. In order to enable content type, click Advanced Settings under General Settings. Once the window is open, select Yes for Allow management of content types.
    adv
  • Click OK to save settings. Note that now the Content Type is shown under Library Settings. Click Add from existing site content types link under Content Type. This opens Add Content Types page.
  • Select Report Server Content Type from Content Types From drop-down. Then move Report Builder Report from left listbox to right listbox.
    Note that if you are not seeing “Report Server Content Types”, that indicates that Add-In has not been properly installed”.
    contenttypes
  • Click OK to save settings. Report Builder Report content type is now appeared under Content Types of Reports library.
    contenttypes2
  • We have to create another library for data connection. Follow same steps for creating the library. Name it as Data Connections. Then enable Allow management of content types as did for Reports library. Then add Report Data Source content type for it.
    contenttypes3

Now SharePoint 2010 is ready for holding reports from Reporting Services 2008 R2. Let’s try to publish some reports to this. Open Business Intelligence Management Studio and create a Reporting Services project. If you have AdventureWorks 2008 Sample Report Project, you can use it for testing. Once the project is open, get the properties of the project. Set following properties;

prp

Now deploy reports and see. Reports will be published to SharePoint site we created. Once published, open the home page of the site (http://dp03:10005) and click on Reports link in left pane. It lists all the reports published.
reports

Click one of reports and see whether it works fine. Here is the output of Company Sales 2008 report.
reports2

All done. Reporting Services 2008 R2 is integrated with SharePoint 2010. I will be exploring more on this, specially SharePoint related things. Once they are explored, I will publish them.


Integrating Sharepoint 2010 and SQL Reporting Services 2008 in 6 easy steps

Configuring Reporting Services 2008 R2 in SharePoint 2010 Integrated Mode – Part I

Integrating Reporting Services with SharePoint is really a fun and it gives extremely user-friendly environment for Reporting Services. There are mainly two ways of integrating Reporting Services with SharePoint. If Reporting Services is installed in Native Mode, Report Explorer and Report Viewer web parts can be used for interacting with reports. When the Reporting Services is installed in SharePoint Integrated Mode, SharePoint takes overall functionalities of Reporting Services, including SharePoint features such as versioning, alerts, and enterprise search. I recently configured SQL Server 2008 R2 in SharePoint 2010 as Integrated Mode, thought to share the experience; the reason for this post. Note that this is the way I configured the integration, you may take different approach for this integration.

I started this with Windows 2008 R2 and configured SharePoint 2010 on it. See this post “Configuring Windows 2008 R2 for SharePoint 2010” if you come across any issue with the installation. When SQL Server Reporting Services is installed, make sure that you select either “Install the SharePoint integrated mode default configuration” or “Install, but do not configure the report server”.

If you need to complete the SharePoint farm installation using non-domain accounts, this post “Complete Farm SharePoint 2010 installation on Single Server using non-domain accounts” shows you the way.

Once the server is ready with SharePoint 2010 and SQL Server 2008 R2, configuration can be started. If you have selected “Install, but do not configure the report server”, you need to configure Reporting Services in SharePoint 2010 mode. Here are steps for configuring it;

  • Open Reporting Services Configuration Manager and connect with Reporting Services instance.
  • Make sure that Report Service status is Started. Notice that Report Server Mode is Native.
  • Open the “Report Service Database” section by clicking the Database navigational tab button. It shows the SQL Server Name, Database Name, and Mode if configured. Click on Change Database button to launch Report Server Database Configuration Wizard. Here is a screenshot of it;
    Untitled
  • Click Next and open the next window of the wizard. Configure the database server which will host the Reporting Services instance. Once authentication is set, click Test Connection and see whether connection can be established successfully. Click Next.
  • Type the database name as ReportServer which is the default name. However you can give a names like ReportServerSharePointIntegrated too. Select the option Report Server Mode as SharePoint Integrated. Click Next to continue.
  • Set credentials that will be used for connecting to the database. If everything is in one box, Service Credentials would be enough.
  • When you click on Next, you will see the summary of what you have entered/selected. Continue with the wizard and complete it.
  • If need to change the port of Web Service URL, go to Web Service URL section by clicking Web Service URL navigational tab button and set it. I have set the port as 20000 and my Web Service URL is http://DP03:20000/ReportServer.
    URL

Next step is downloading Reporting Services Add-in for SharePoint 2010. Here is the link for downloading it:http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=b3bebf9d-d86d-48cd-94e2-0639a846be80.

Once it is downloaded, start installing it. Starting screen would be this;
AddIn

Complete the installation. Now all required parts are ready. Next is configuring SharePoint for Reporting Services. Open SharePoint 2010 Central Administration and click on General Application Settings link.
central

Once the General Application Settings is open, a section called Reporting Services can be seen which allows managing integrating settings.
central2

The link Reporting Services Integration opens the window where Report Server Web Service URL and Authentication Mode can be set. The Report Server Web Service URL should be the URL that has been configured with Web Service URL navigational tab of Reporting Services Configuration Manager. Authentication mode can be either Windows Authentication or Trusted Authentication. Since everything is in one box, Windows Authentication would be fine with this.

In order to user Trusted Authentication, a trusted account has to be predefined. When Trusted Authentication is used, Report Server has no knowledge on the user connected to the SharePoint. Trusted account impersonates connected SharePoint user and will be used for accessing the Report Server. Trusted Authentication is usually used with Form Authentication or windows authentication without AD or Kerberos. Here is my screen;
IntegrationSet Server Defaults under Reporting Services allows changing default server settings for Reporting Services. Some of this elements can be changed are; Number of Snapshots, Ad-Hoc Reporting and Client-Side Printing.

Now the integration is done. The SharePoint is fully integrated with Reporting Services. We need a hosting environment for Reporting Services. Since Reporting Services Add-In has added necessary content types for the Farm, reports can be added to any site. Or else, a new site can be created for hosting Reporting Services reports and connections. See Part II for creating a site, configuring libraries and content type, and publishing reports from BIDS.

Monday, July 12, 2010

Sharepoint Download Zipped List Items !

Project Description
This Custom UI Actions for Sharepoint extends the lists action menu to allow users to zip document library items and download all of them either with or without version

Features

  • Download all document library items
  • Keep the folder hierarchy
  • Versions: if you are caring about document versions you can download them as well
  • Ability to download only the selected view items instead of all list items


The new menu added to the sharepoint document library actions menu
1-Menu_resize.jpg
After clicking over the menu item
downloadbox_resize.jpg

the compressed file downloaded
ZipExplorer_resize.jpg

the compressed file downloaded with the files versions
ZipExplorer_versions_resize.jpg


Known Issues

  • Arabic file names: arabic file names are not downloaded correctly
  • The tool uses the system temporary directory to export the list items and compress it, so you need to watch this folder and manage a clean up mechanism
Sharepoint Download Zipped List Items