Wednesday, April 29, 2009

Customize SharePoint Team Site Home Page

Hi All,
As part of most of the client requirements we need to customize the home page of the SharePoint team site. e.g Removing left hand quick launch, hiding header etc.
Here are some samples you can use to customize the home page. You need to add a Content Editor Web Part on the home page and make it invisible by unchecking the visible attribute.

1. Hiding Left Hand Quick Launch


2. Hiding the Page Title (Home) and showing the site title in bold and white color




3. Changing the background color of the title area frame




As you would have noticed that i have used the css classes used by SharePoint and overridden them. For a complete list of stylesheet classes refer:
http://www.sharepointcustomization.com/resources/tipstricks/wss_cssguide.htm
Most of the classes are used both in SharePoint 2003 and 2007 version.

Hope this will help.
For any other issue write to us at sharepointkings@gmail.com

Tuesday, April 21, 2009

SPFieldUserValue and SPFieldUserValueCollection

Most of the time we have seen that people are using people and group field, and for fetching that field they are just using string manipulation for taking login name or name.
And that is totally wrong.

So here is simple code snippet for how to fetch user from SharePoint list.

To do this you have to use SPFieldUserValue object provided by SharePoint object model
Here is the start up

SPSite site = new SPSite("http://spvm");
SPWeb web = site.OpenWeb();
SPList list = web.Lists["DemoList"];
SPListItem item = list.GetItemById[1];
SPFieldUserValue objUserFieldValue = new SPFieldUserValue(web, item["User"].ToString());


Once you get this object SPFieldUserValue ( objUserFieldValue) then you can retrieve each and every property of that user by following way.

objUserFieldValue.User.LoginName;
objUserFieldValue.User.Name;
objUserFieldValue.User.ID;
objUserFieldValue.User.Groups;
objUserFieldValue.User.Roles;
objUserFieldValue.User.Email;
objUserFieldValue.User.Sid;
objUserFieldValue.User.UserToken;


So all the properties of SPUser will be available and you can use that the same way you treat SPUser field.

For group you can like this way

If(objUserFieldValue.User==null)
//Then selected value is group.
Else
//Selected value is user.


For allowing multi selection we have to use collection

SPFieldUserValueCollection objUserFieldValueCol = new SPFieldUserValue(web, item["User"].ToString());
for (int i = 0; i < objUserFieldValueCol.Count; i++)
{
SPFieldUserValue singlevalue = objUserFieldValueCol[i];
if (singlevalue.User == null)
//then single value is group
else
//singlevalue is user and you can use all SPUser properties.
}


This is same concept as SPLookupFieldvalue and this is also good practice to imbibe.

Creating Custom Toolbar and ToolBarbutton

Hi All,

Many times we may require creating a custom toolbar, just like a toolbar that you can see when you click on View Item link of any item in list or document library and on DispForm.aspx.

Here we will also achieve the same thing. We will create one custom toolbar and also create custom toolbar button and add the buttons to the toolbar and set the different URLs to them.

First we need to create a ToolBarbutton. ToolBarButton class is available in Microsoft.Sharepoint.WebControls. ToolBarButton.

Here go to 12 hives control templates and observe one ascx control which is ToolBarButton.ascx. We will use this.

So first for an example in webpart we need to render the toolbar with toolbarbuttons in it with different URLs.

So we will proceed like this.

ToolBarButton toolbuttonNew =
(ToolBarButton)Page.LoadControl("~/_controltemplates/ToolBarButton.ascx");
toolbuttonNew.Text = "New";
toolbuttonNew.ImageUrl = "/_layouts/images/customimage.GIF"; //choose your own image url
toolbuttonNew.NavigateUrl = {url where you want to navigate on click};



Same way, you can have as many ToolBar buttons as you want.

Now let’s say you are done with the buttons, now get the reference of the ToolBat itself. Same again in 12 hive’s control template, you can observe ToolBar.ascx. so we will use this.

ToolBar toolbar = (ToolBar)Page.LoadControl("~/_controltemplates/ToolBar.ascx");


Now, add button to it

toolbar.Buttons.Controls.Add(toolbuttonNew);


and finally add toolbar to the webpart.

Controls.Add(toolbar);


That’s it. You are done with your job.

SharePoint calculated column and jQuery Highlight row

Hi All,
Here I am writing new blog after long time I highly apologies to our all regular SharePointKings readers. I have explore what you can do by SharePoint calculated column and jQuery here is small practical stuff follow the instructions and do it yourself you will surely enjoy this work I am sure.
Sometimes you need to represent SharePoint List in terms of legend like in map. Say for example you have result list and you want to show those Student who got less than 35% marks Should Have “Red” Legend, those who got 100% marks with “Blue” Legend , those who got >65% with “Pink” Legend , those who got >70% with Yellow, marks > 60 with Green.

Follow the steps
1. Create Result SharePoint custom list.


2. Create column StudentName single line text.

3. Create Column Color with Calculated Column.


Copy and Paste following code in formula.
=IF((Marks*100)>=100,"#0000FF",IF((Marks*100)>=70,"#FFFF00",IF((Marks*100)>60,"#FF00FF",IF((Marks*100)>=35,"#00FF00","#FF0000"))))

4. Create another column called Display.


Copy and paste following formula
="<DIV style='border: 1px "&Color&" solid;background-color:"&Color&";color:#FFFFFF;'>"&Marks*100&"<DIV>"

5. Now your fields looks like this


6. Open new form and Add Student Name and Marks obtained by him.
7. Once you enter marks for student your SharePoint list looks like this


8. Edit Page

9. Add ContentEditor webpart.

10. Add Following Code in Source Editor

<script type="text/javascript">
if(typeof jQuery=="undefined"){
var jQPath="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/";
document.write("<script src='",jQPath,"jquery.min.js' type='text/javascript'><\/script>");
}
</script>

<script type="text/javascript">


$(document).ready(function(){
$(".ms-vb2:contains('<DIV')").each(function(){
var tempDIV = document.createElement ("DIV");
tempDIV.style.cursor = "pointer";
tempDIV.innerHTML = $(this).text();
$(this).text("");
$(this).append(tempDIV);

});
});
</script>

11. Click ok button
12. Now your result SharePoint list look like


Cool……………
It works now you can do many more things using jQuery and Calculated column.
For calculated column refer


do let us know your experience with this post.
Cheers,

Monday, April 20, 2009

SPFieldLookupValue and SPFieldLookupValueCollection

If you want to retriever lookup field from list then good practice is to use SPFieldLookupValue rather than string manipulation.

Here is the example how to use retrieve lookup value from SharePoint list.

SPSite site = new SPSite("http://spvm");
SPWeb web = site.OpenWeb();
SPList list = web.Lists["DemoList"];
SPListItem item = list.GetItemById(1);
SPFieldLookupValue objLookupFieldValue = new SPFieldLookupValue(item["lookup"].ToString());


Once you get this SPFieldLookupValue (objLookupFieldValue) object you will get following properties.

objLookupFieldValue.LookupValue = value of the parent list item.
objLookupFieldValue.LookupId = item id of the parent list item (reference id)


These are small things that will help you to make your software robust.
If Lookup is multi select then you have to use SPFieldLookupValueCollection.

SPFieldLookupValueCollection objLookupFieldValueCol = new SPFieldLookupValueCollection(item["lookup"].ToString());
for (int i = 0; i < objLookupFieldValueCol.Count; i++)
{
SPFieldLookupValue singlevalue = objLookupFieldValueCol[i];
//use singlevalue with same way as single select
}

Friday, April 17, 2009

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.

How to Handle / prevent List deletion from site

Hi All,

In our project there was a requirement where few lists once created, has to be there. They can not be deleted. Even not by the site administrator.

So a problem is we do not have any event called ListDeleting or ListDeleted. So how to handle this situation.

I dig a bit with the properties of list and document library and found something that I would like to bring it for sharing with you all.

Two ways I found. One is not to give any option for deleting list. Means options that we find in permissions and management in list settings, we don’t display that option at all.

Ok, how to achieve it. Simple. I found one property which is interesting of List and document library. Name of the property is AllowDeletion. Set it to false and update the list. The option for Delete this list is gone.!!!!

This is just sample code for this.

SPWeb objWeb = SPContext.Current.Web;

SPList objList = objWeb.Lists["{List }"];

objWeb.AllowUnsafeUpdates = true;

objList.AllowDeletion = false;

objList.Update();

objWeb.AllowUnsafeUpdates = false;



Now what about the second option. Ok, one more interesting part. As we do not have event handler like ListDeleting but we do have ItemDeleting. So what we can do is create one event handler class, attach to the list that you do not want to be deleted by anybody and write down some code stuff like this and even you can capture details like who tried to delete the list. Capture those data and add it in to your other custom list or database or what ever media that you prefer.

Here is interesting thig is when you delete the list, then also ItemDeleting will be called and you will get ListItemId as 0 because you are not deleting any Item from list.


public override void ItemDeleting(SPItemEventProperties properties)
{

int itemid = properties.ListItemId;

if (itemid == 0)
{
properties.Cancel = true;
properties.ErrorMessage = "You are not allowed to delete the
list";
string strLoggedInUserWhoTriedToDelete = properties.UserLoginName ;

}



}


That is it. You are done with your job…!!!

Thursday, April 16, 2009

Strange behavior of SharePoint list versioning

Recently we are facing problem with SharePoint list versioning.
List item version is retrieving different (wrong) value.

We have a scenario where we have to compare two version of same list item.
So we think we will use object model and show user what item changed.
But when we had done that we are not able to understand what happen.
We are getting strange behavior in date time field and User (people picker) field.
We are not changing date field but when we are fetching previous version then we are getting around 7 hours different time and sometime because of this it will change the date also.

So for demo I had created a list with two columns
1) “Customuser”
2) “CustomDate”

Then unable the versioning on that list.
Then add item in that list.
Then change the title only, do not change other field what I found is here.
First Version


Second Version



Below is the code to check
ColumnName = "CustomDate";
CurrentVersion = item[ColumnName].ToString();
OldVersion = item.Versions.GetVersionFromLabel("2.0")[ColumnName].ToString();
Values
Currentversion = 4/16/2009 12:00:00 AM
Old version = 4/16/2009 7:00:00 AM



ColumnName = "CustomUser";
CurrentVersion = item[ColumnName].ToString();
OldVersion = item.Versions.GetVersionFromLabel("2.0")[ColumnName].ToString();

Values
CurrentVersion = 7;#SPVM\parth
Old version = 7;#SPVM\parth,#SPVM\parth,#,#,#SPVM\parth


We gor shocked when we checked Created and Created by (Auther) column.
And that column also gives some strange detail.

ColumnName = "Created";
CurrentVersion = item[ColumnName].ToString();
OldVersion = item.Versions.GetVersionFromLabel("2.0")[ColumnName].ToString();
CurrentVersion = 4/16/2009 9:42:41 AM
Old version = 4/16/2009 4:42:41 PM


ColumnName = "Created By";
CurrentVersion = item[ColumnName].ToString();
OldVersion = item.Versions.GetVersionFromLabel("2.0")[ColumnName].ToString();
CurrentVersion = 1;#SPVM\administrator
OldVersion = 1;#SPVM\administrator,#SPVM\administrator,#administrator@sharepoint.local,#,#SPVM\administrator


Now we don’t know how to solve this problem til now
We just share this as we found this scenario. May be is this a bug of sharepoint or we are not able to understand how this functionality works :) ?

Saturday, April 4, 2009

Creating ECB menu for specific list or document library

Hi All,

Many times requirement comes like we want to have a ECB menu item but for specific list or specific document library only not for all lists or not for all document library.

Let me give you very simple and short solution.

When you are creating your list or document library. Just create unique TemplateType in your elementmenifest.xml file.

let's say "100110" or any unique number which is not there in this list.

public enum SPListTemplateType
{
InvalidType = -1,
GenericList = 100,
DocumentLibrary = 101,
Survey = 102,
Links = 103,
Announcements = 104,
Contacts = 105,
Events = 106,
Tasks = 107,
DiscussionBoard = 108,
PictureLibrary = 109,
DataSources = 110,
WebTemplateCatalog = 111,
UserInformation = 112,
WebPartCatalog = 113,
ListTemplateCatalog = 114,
XMLForm = 115,
MasterPageCatalog = 116,
NoCodeWorkflows = 117,
WorkflowProcess = 118,
WebPageLibrary = 119,
CustomGrid = 120,
DataConnectionLibrary = 130,
WorkflowHistory = 140,
GanttTasks = 150,
Meetings = 200,
Agenda = 201,
MeetingUser = 202,
Decision = 204,
MeetingObjective = 207,
TextBox = 210,
ThingsToBring = 211,
HomePageLibrary = 212,
Posts = 301,
Comments = 302,
Categories = 303,
IssueTracking = 1100,
AdminTasks = 1200,
}

And when you create your CustomAction for ECB, just make sure RegistrationID should match with your unique ID of TemplateType of your list.

<CustomAction
Id="CC5EA7DE-CF2E-49ca-9629-1DAB00A06700"
RegistrationType="List"
RegistrationId="100110"
Location="EditControlBlock"
Sequence="333"
Title="Send to custom page">
<UrlAction
Url="{SiteUrl}/_layouts/MyPage.aspx?List={ListId}&amp;ID={ItemId}"/>

That's it. you are done with your task. now you will have ECB item only for your specific list or specific document library.

Thank you



Share your SharePoint Experiences with us...
As good as the SharePointKings is, we want to make it even better. One of our most valuable sources of input for our Blog Posts comes from ever enthusiastic Visitors/Readers. We welcome every Visitor/Reader to contribute their experiences with SharePoint. It may be in the form of a code stub, snippet, any tips and trick or any crazy thing you have tried with SharePoint.
Send your Articles to sharepointkings@gmail.com with your Profile Summary. We will Post them. The idea is to act as a bridge between you Readers!!!

If anyone would like to have their advertisement posted on this blog, please send us the requirement details to sharepointkings@gmail.com