Monday, October 24, 2011

How to fix: Recurring Meeting Workspace error

I recently developed a Custom Master Page.Every thing worked fine but  When I selected the custom master page for Meeting workspace it started throwing a java script error ‘g_InstanceID’ is undefined.
After some digging back I came to know that the default master page for meeting Workspace is MWSDefault.master which contains the PropertyBag web control.
Started searching and found the solution here.

Thursday, September 22, 2011

Iterating against Multiline Field

We all know how to iterate on single line of text field in SharePoint.But its a bit tricky when it comes to Multiline Text field.I think its more hassle than Lockup column.
Here is how we get the data from the Field.
SPListItemCollection itemCol = List.GetItems(query);
 SPListItem item = itemCol[i];
SPFieldMultiLineText myField =item.Fields.GetField("fieldName") as SPFieldMultiLineText;
string myString=myField.GetFieldValueAsText(item["fieldName"]);

Even though the string gets with \r\n in order to diplay on console here is how to code
string temp = item["myField"].ToString();
string[] fieldValue = temp.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
The above method helps in removing the \r and \n present.
If you are show on web .use a textbox and set the textmode property to "multiline".This will automatically display in same format present as in SharePoint List.
Ex:<asp:TextBox ID="txtField" runat="server" TextMode="MultiLine"></asp:TextBox>
txtField.Text=myField.GetFieldValueAsText(item["fieldName"]);

Tuesday, August 30, 2011

Using CAML to get items based on DateTime

Most of the Times we work on retrieve items from List or Document Library based on different Columns.This article is to target the datetime column.

Scenario 1: I want to get items which are greater than or equal to Today's date
<Query><Where><Geq><FieldRef Name="EndDate" /><Value IncludeTimeValue="TRUE" Type="DateTime"><Today /></Value></Geq></Where><OrderBy><FieldRef Name="StartDate" Ascending="False" /></OrderBy></Query>

The attribute "Today" helps in defining the date to be Current Date
Scenario 2: We Want to get result from say 5 days from Today
<Query><Where><Geq><FieldRef Name="EndDate" /><Value IncludeTimeValue="TRUE" Type="DateTime"><Today  Offset="5"/></Value></Geq></Where><OrderBy><FieldRef Name="StartDate" Ascending="False" /></OrderBy></Query>

The Attribute "Offset" defines the No.of days we want to go back




Tuesday, August 16, 2011

Calling List webservice using Jquery

Most of the times we generally use object model to query SharePoint List.But not all development environments gives you an option of custom code.So JQuery along with Content Editor WebPart.
Here is the scenario I had a case of using dataview webpart which needs to be filtered basing on criteria, as we can create a parameter based on query string.In this case I am intrested in the filter rather than how to create DVWP.So coming to the coding part
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>

<script type="text/javascript">
$(document).ready(function() {
var soapEnv =
"<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'> \
<soapenv:Body> \
<getlistitems xmlns='http://schemas.microsoft.com/sharepoint/soap/'> \
<listname>AppStatusList</listName> \
<viewfields> \
<viewfields> \
<fieldref Name='Title' /> \
</ViewFields> \
</viewFields> \
</GetListItems> \
</soapenv:Body> \
</soapenv:Envelope>";

$.ajax({
url: "http://balaapd004/dept/cs/test/_vti_bin/lists.asmx",
type: "POST",
dataType: "xml",
data: soapEnv,
complete: processResult,
contentType: "text/xml; charset=\"utf-8\""
});

$('#ddlSelect').change(function() {
//var selectedValue=
$('#txtResult').val($('#ddlSelect option:selected').text());
});
});

function processResult(xData, status) {
var listItems="";

$(xData.responseXML).find("z\\:row").each(function() {
listItems+= "<option value='" + $(this).attr("ows_ID") + "'>" + $(this).attr("ows_Title") + "</option>";
$("#ddlSelect").html(listItems);

});
}
</script>

<select id="ddlSelect">
</select>
<input type="text" id="txtResult" />

Monday, August 1, 2011

Extension Method to iterate against any control on a Page

We all know that in order to iterate against any control on page a method we generally go for is
Page.FindControl.
But this is a bit tedious process when we associate the same page with Master Page which adds one more foreach loop on the top and the best vs bad part is it gives you a bit of debugging time.

I think the best way of doing this is using the Extensions method which comes with c# 3.0

public static class myExtensions
        {        
            public static IEnumerable<T> AllControls<T>(this Control ctrl) where T : Control
            {
                bool find = ctlr is T;
                if (find)
                {
                    yield return ctrl as T;
                }
                foreach (var child in ctrl.Controls.Cast<Control>())
                {
                    foreach (var item in AllControls<T>(child))
                    {
                        yield return item;
                    }
                }
            }
        }

This gives you an ease in different ways as it can used along with Lambda expressions like this
Page.AllControls<CheckBox>().Where(c => c.Checked);

or simply to iterate on the control you want to find
 var chkBox = Page.AllControls<CheckBox>();

foreach (CheckBox i in chkBox)
       {
    //Your code
       }

Thursday, July 28, 2011

Passing Property Value from WebPart to USer Control in MOSS

Any time came across a scenario where you have to pass property value from WebPart hosting the UserControl to pass value in SharePoint 2007.
Here is a small example how you can achive this.
The Solution structure
As you see by default you can't see the User Control template ,the easiest way of  doing this Unload the project "Right Click"  click as shown in the image
Add this GUID under the section where it says <ProjectTypeGuids>
{349C5851-65DF-11DA-9384-00065B846F21};
Save it and reload the project "Bingo" you can see the User Control template.
WebPart Code :
 public class ValueToUC : System.Web.UI.WebControls.WebParts.WebPart
    {
        private bool _error = false;
        private string _myName = null;
        private const string _ascxPath = @"~/_CONTROLTEMPLATES/ValueToUC/ValueUC.ascx";
        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [System.ComponentModel.Category("My Properties")]
        [WebDisplayName("MyName")]
        [WebDescription("MyName")]
        public string MyProperty
        {
            get { return _myName;  }
            set { _myName = value; }
        }
     
        public ValueToUC()
        {
            this.ExportMode = WebPartExportMode.All;
            this.ChromeType = PartChromeType.None;
        }     

        protected override void CreateChildControls()
        {
            if (!_error)
            {
                try
                {
                    base.CreateChildControls();

                    ValueUC uc = (ValueUC)Page.LoadControl(_ascxPath);
                    uc.parentWp = this;
                    this.Controls.Add(uc);                                                     
                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }
            }
        }
     
        private void HandleException(Exception ex)
        {
            this._error = true;
            this.Controls.Clear();
            this.Controls.Add(new LiteralControl(ex.Message));
        }
    }

User Control Code:
public partial class ValueUC : System.Web.UI.UserControl
    {
        public ValueToUC parentWp
        {
            get;
            set;
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            lblName.Text = parentWp.MyProperty;
        }
    }
As you observe I am using the WebPart class as a property which will help in getting the value to the User Control.

Thursday, July 21, 2011

Create a Application Page with code behind

We can create an application page using inline code but I think its more elegant to use code behind.
I am using WSPbuilder for the project.The solution structure
Some things to be taken care of in the aspx page are
  • Get Full Assembly name information
<%@ Page Language="C#" MasterPageFile="~/_layouts/application.master" Inherits="codeBehindPage.codeBehindPage,codeBehindPage, Version=1.0.0.0, Culture=neutral, PublicKeyToken=afd867e29b3b4c59" %>

<asp:content  contentplaceholderid="PlaceHolderMain" runat="server">
<asp:button id="Button1" onclick="Button1_Click" runat="server" text="Button"/>
<br/>
<asp:GridView ID="gv" runat="server"/>
<asp:Content>

And now the code Behind for the button click event.
Important things to note
General Tendency is to get item from SharePoint List using the SPListItemCollection and bind to the GridView as it can understand the collections and display in tabular format which is where it gives the famous error irrespective of the collection containing results
Value does not fall within the expected range.   at Microsoft.SharePoint.SPFieldMap.GetColumnNumber(String strFieldName)
   at Microsoft.SharePoint.SPListItemCollection.GetRawValue(String fieldname, Int32 iIndex)
   at Microsoft.SharePoint.SPListItem.GetValue(SPField fld, Int32 columnNumber, Boolean bRaw)
   at Microsoft.SharePoint.SPListItem.GetValue(String strName, Boolean bThrowException)
   at Microsoft.SharePoint.SPListItem.get_Name()


So the best way to deal is as shown below

namespace codeBehindPage
{
    public partial class codeBehindPage : System.Web.UI.Page
    {      
        protected void Page_Load(object sender, EventArgs e)
        {
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            SPWeb site = SPContext.Current.Web;
            SPList list = site.Lists["Customer Service Events"];
            SPQuery query = new SPQuery();
            query.Query = "";
            query.ViewFields = "";
                //""+
            SPListItemCollection itemcol = list.GetItems(query);

            gv.DataSource = list.GetItems(query).GetDataTable();
            //gv.DataSource = list.GetItems(query);
            gv.DataBind();
        }
    }
}

Friday, July 8, 2011

How to delete items from SharePoint List

Many of us might think whats new in deleting the item from Sharepoint List but there are some interesting facts to understand about this process.
You might come across this wierd error
  "Collection was modified; enumeration operation may not execute"
The error is same irrespective of  using a for or a foreach loop.
Let me Explain what happens in the background when delete using the follolwing code
                    SPList gallery = site.Lists["Your List"];
                    SPListItemCollection itemCol = gallery.Items;
                    foreach(SPListItem item in itemCol)
                    {
                        item.Delete();
                       gallery.update();                     
                    }                                   
Now whenever this code executes for each item deletion as the number of items gets deleted ,the second item gets the first index and that the reason for error.
You can also do the same like this
for (int i = 0; i < list.Items.Count; i++) {    
    list.Items.Delete(0);
}
This skips the items or randomly deletes the items in some scenarios.
So Best ways for deletion process:
Method 1 when deleting all items :
for (int i = list.Items.Count - 1; i >= 0; i--) {
    list.Items.Delete(i);
}
Method 2:IF a condition as to be met before deletion
So the best way of doing the deletion process is      
                    SPList gallery = site.Lists["YourList"];
                    SPListItemCollection itemCol = gallery.Items;
                    for (int i = itemCol.Count -1;i>=0; i--)
                 {
                        if (itemCol[i].Title.Equals("SomeName"))
                        {
                           itemCol[i].Delete();
                           gallery.Update();
                        }
                    }
              

Thursday, July 7, 2011

How to add List Template to SharePoint Site

So far we might came across adding WebParts,Pages,Page Layout,CSS you name it any SharePoint artifacts are deployed using the famous Feature.xml and Elements.xml.
Here is how you should define your Elements.xml
  <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Url="_catalogs/lt" Name="Summary Links.stp" Path="SummaryListTemplate">
        <File Url="Summary Links.stp" Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE">
        <Property Name="Title" Value="StpTest" />
        <Property Name="Language" Value="1033" />
        <Property Name="FeatureID" Value="{00BFEA71-2062-426C-90BF-714C59600103}" />
        File>
    Module>
Elements>
In My Project I have kept the list template under Features/SummaryListTemplate hence the path in the elements.xml

Wednesday, June 29, 2011

Deploy Welcome Page in Team Sites - Method3

Method: 3
We will deploy the new Home Page to the 12th hive and not to the Layouts Folder because I want the look and feel of the URL as http://sites/test/CustomPages/Home.aspx but not like http://sites/test/_Layouts/Home.aspx
The way of doing this is through Feature Receiver when activated sets the new Home Page and deactivated sets to the older Home Page.
Solution Structure

Feature.xml:
The Element Manifest Section should be like this
  <ElementManifests>
    <ElementManifest Location="elements.xml"/>
    <ElementFile Location="CustomPages\Home.aspx"/>
  ElementManifests>
Elements.xml:
<Module Name="CustomPages" Path="CustomPages" >
     <File Path="Home.aspx" Url="CustomPages/Home.aspx" Type="Ghostable"/>
  Module>
Here Comes Our FeatureActivated code:
public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {            
            SPWeb web = properties.Feature.Parent as SPWeb;    
           // back up the original home page
           SPFile defaultPage = web.Files["default.aspx"];
           defaultPage.MoveTo("default-old.aspx");
           //updating the navigation
           SPFolder rootFolder =web.RootFolder;
           rootFolder.WelcomePage = "CustomPages/Home.aspx";
           rootFolder.Update();
        }
FeatureDeactivating code:
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        { 
            //CustomPages/Home.aspx
            SPWeb web = properties.Feature.Parent as SPWeb;
            SPFolder rootFolder = web.RootFolder;           
            // restore the back up
            SPFile originalDefaultPage = web.Files["default-old.aspx"];
            originalDefaultPage.MoveTo("default.aspx");
           //resetting up the navigation 
            rootFolder.WelcomePage = originalDefaultPage.ToString();
            rootFolder.Update();            
        }

Deploy Welcome Page in Team Sites-continuation

Code for the buttons are Part1

protected void Page_Load(object sender, EventArgs e) {
if (!Page.IsPostBack) {
if (txtWelcomePage != null) {
using (SPSite siteCollection = new SPSite(SPContext.Current.Web.Url))
{
using (SPWeb site = siteCollection.OpenWeb())
{
txtWelcomePage.Text = site.RootFolder.WelcomePage;
}
}
}
}
}
protected void ButtonOkUpdatePageClick(object sender, EventArgs e) {
if (!string.IsNullOrEmpty(txtWelcomePage.Text)) {
using (SPSite siteCollection = new SPSite(SPContext.Current.Web.Url))
{
using (SPWeb site = siteCollection.OpenWeb())
{
SPFolder rootFolder = site.RootFolder;
rootFolder.WelcomePage = txtWelcomePage.Text;
rootFolder.Update();
SPNavigationNode homeNode = site.Navigation.TopNavigationBar.Navigation.Home;

//This is to update the default navigation
homeNode.Url = SPUrlUtility.CombineUrl(site.Url, txtWelcomePage.Text);
homeNode.Update();

Response.Redirect(SPUrlUtility.CombineUrl(site.Url, "/_layouts/settings.aspx"));
}
}
}
}
protected void ButtonCancelUpdatePageClick(object sender, EventArgs e) {
// redirect to the site's settings page
Response.Redirect(SPUrlUtility.CombineUrl(SPContext.Current.Web.Url, "/_layouts/settings.aspx"));
}
And Coming to the Limitations as you might have seen there is no option to roll back the new Home Page to the default.aspx.So Here Comes the Method3 which gives us that control.

Deploy Welcome Page in Team Sites

In Publishing sites we have an option of setting up Welcome Page ,but this option is not present in Team Sites.
We can achieve this in different ways
  1. Using SharePoint Designer
  2. Deploy a Feature which gives you a Provision of setting up the welcome Page.
  3. Deploy a Feature which will set the new page as Welcome Page on Feature activated and resets the older default when deactivated.
I will discuss methods 2 and 3 here
Method 2:
This is how the Solution structure looks like
Below is the elements.xml where we define the Custom Actions option
<elements xmlns="http://schemas.microsoft.com/sharepoint/">
<customaction>
Id="UserGroupAdminLinkForSettings"
GroupId="Customization"
Location="Microsoft.SharePoint.SiteSettings"
RequireSiteAdministrator="TRUE"
Sequence="120"
Title="Welcome Page">
<urlaction url="_layouts/WelcomePage/WelcomePage.aspx"></urlaction>
</customaction>
</elements>

Feature.xml I have defined to be as Web
This is How the option looks like


When you click on the link this is how you see. Continuation 

Understanding the Application Page CopyUtil.aspx

I have recently came to know about an Application Page called CopyUtil.aspx.
Ever came across a scenario where you have to navigate either to Dispform or EditForm by passing in parameters like siteId,ListId and ItemId.
These are some of the parameters that this page expects which will help you in smooth navigation.
Mostly this is used with SPSiteDataQuery .
The URL would look like this
/_layouts/CopyUtil.aspx?Use=id&Action=dispform&ItemId="itemID"&ListId="listID"&WebId="webId"&SiteId="siteId"
The Action Parameter is the one you have to decide ,it might be dispform or editform.

Friday, June 24, 2011

To Find if the Page in MOSS is in Design Mode

Some Times we have to make the Jquery/JavaScript run when its not in the design mode.
I don't know how many of us has noted this tag "MSOLayout_InDesignMode" .This is a hidden HTML field present on the page. So using that its simple.

The HTML looks like this:
<input type="hidden" name="MSOLayout_InDesignMode" id="MSOLayout_InDesignMode" value="" />
if (document.getElementById("MSOLayout_InDesignMode").value != "1")
{
//do something
}
else
{
//do something
}

Thursday, June 23, 2011

Simple ways to check if List exist in MOSS using Lambda expressions

In MOSS we don't have a pre defined method of to check if a List Exist .Here comes new feature of  C# to extensions to rescue.

public static bool ListExists(this SPWeb web, string listName)
        {
            return web.Lists.Cast().Any(l => l.Title.Equals(listName, StringComparison.OrdinalIgnoreCase));
        }
Alternate for the Same

public static bool ListExists(SPWeb web, string listName)
         {
            var lists = web.Lists;
            foreach (SPList list in lists)
            {
                if(list.Title.Equals(listName))
                    return true;
            }
            return false;
       }

URL Encoding using JQuery

Ever came across a scenario where you have to encode using JavaScript/JQuery other than using C# especially in SharePoint.One of my experience User required a link when clicked to be passed as filter value to the Document Library/List.If the value is simple Text its easy but if the value contains Ex: Harrison & Thomas there is the problem .If you pass in the mentioned value as a  Query string parameter it understands as two arguments and hence the Library is not filtered .Here comes the encoding part as we can extended the Jquery Library function.

$.extend({URLEncode:function(c){var o='';var x=0;c=c.toString();
var r=/(^[a-zA-Z0-9_.]*)/;
  while(x
    if(m!=null && m.length>1 && m[1]!=''){o+=m[1];x+=m[1].length;
    }else{if(c[x]==' ')o+='+';else{var d=c.charCodeAt(x);var h=d.toString(16);
    o+='%'+(h.length<2?'0':'')+h.toUpperCase();}x++;}}return o;},
URLDecode:function(s){var o=s;var binVal,t;var r=/(%[^%]{2})/;
  while((m=r.exec(o))!=null && m.length>1 && m[1]!=''){
  b=parseInt(m[1].substr(1),16);
  t=String.fromCharCode(b);o=o.replace(m[1],t);}return o;}
});

Now you can call this  function as
$.URLEncode($(this).attr("title"));

Hint: Place this script below the List in Content Editor WebPart

Print Functionality using Javascript on MOSS

One of the Limitation in SharePoint is having no option to print for the users.Even though there are lot of solutions given by third party vendors or even solution mentioned in Codeplex or SharePoint Tips and Tricks blog I feel this can be done also using Java Script.
function printWebPart(tagid){
var WebPartElementID = tagid;
var bolWebPartFound = false;
if (document.getElementById != null)
{
//Create html to print in new window
var PrintingHTML = '\n\n';
//Take data from Head Tag
 if (document.getElementsByTagName != null)
{
var HeadData= document.getElementsByTagName("HEAD");
if (HeadData.length > 0)
PrintingHTML += HeadData[0].innerHTML;
}
PrintingHTML += '\n\n\n';
var WebPartData = document.getElementById(WebPartElementID);
if (WebPartData != null)
{
PrintingHTML += WebPartData.innerHTML;
bolWebPartFound = true;
}
else
{ bolWebPartFound = false;
 alert ('Cannot Find Web Part');
 }
} PrintingHTML += '\n\n'; //Open new window to print
if (bolWebPartFound)
{
//alert("clicked print");

var PrintingWindow = window.open("","PrintWebPart", "toolbar,width=800,height=600,status=yes,resizable,menubar");
PrintingWindow.document.open();
PrintingWindow.document.write(PrintingHTML);
PrintingWindow.document.close();
// Open Print Window
PrintingWindow.print();
PrintingWindow.close();
 }
}

Interesting Facts about DateTime and Varchar/Nvarchar in c# vs DataBase

When we insert data from either a console or ASP.net app to DataBase there are some interesting pit falls in a way Data types are handled from both ends.
We know that string in c# accepts null/empty values and you also have designed in the DB whether as Varchar/Nvarchar and allowing null.
When we insert value in the  DB it will not put null instead it throws error .So the best way to do is
Ex:
cmd.Parameters.Add("@Title", SqlDbType.NVarChar).Value = DBNull.Value;
Similarly for the DateTime
 cmd.Parameters.Add("@OrgTargetDate", SqlDbType.DateTime).Value = System.Data.SqlTypes.SqlDateTime.Null; 

Verify if a Field Exist in MOSS 2007

I had a scenario where I have to iterate the same List name in a Site Collection but different sub sites.
Interesting fact is the list has different Fields.
Even though we don't have a method to verify if a list exist but there is one to check if a Field exist in SharePoint List/Document Library.

 SPList list = site.Lists["Your List Name"];
list.Fields.ContainsField("Yout Field Name")