Thursday, December 22, 2011

SharePoint Batch Deleting List Items Programatically

While working on a custom SharePoint solution, I had a requirement to delete multiple list items one time rather than deleting one by one.
Example: Delete only the items from a list which doesn't have value for a custom column.

When i think of the solution i couldn't make new SPListItemCollection object out of the items which needs to be deleted, which is possible in regular c# application development.
However in SharePoint we can do the batch delete of list items using CAML script.
The CAML script needs to be generated for the items which needs to be deleted as below.

Get the list items:
SPListItemCollection items = spList.Items;
Generate CAML Script:
StringBuilder methodBuilder = new StringBuilder();

string batchFormat = "" +
"{0}"; //{0}-methodFormat

string methodFormat = "" + //{0}-Unique Value for each Item
"{1}" + //{1}-List Guid
"{2}" + //{2}-List ItemID
"Delete" +
"";

// Build the CAML delete command script.
foreach (SPListItem item in items)
{
    //get the custom column value
    string customColumnValue = string.Empty;
    if (null != item["CustomColumnName"])
        customColumnValue = item["CustomColumnName"].ToString();
    
    //check whether custom column is empty
    if (string.IsNullOrEmpty(customColumnValue))
    {
        methodBuilder.AppendFormat(methodFormat, item.ID, item.ParentList.ID, item.ID);
    }
}

//batch delete script.  
string batchDeleteScript = string.Format(batchFormat, methodBuilder.ToString());
Execute CAML Script:
spWeb.ProcessBatchData(batchDeleteScript);
Similarly batch updating script can also be generated. Look at the detailed post here for code.

SharePoint Batch Updating List Items Programatically

While working on a custom SharePoint solution, I had a requirement to update multiple list items one time rather than updating one by one.
Example: Update only the items in a list which doesn't have value for a custom column (update with some value).

When i think of the solution i couldn't make new SPListItemCollection object out of the items which needs to be updated, which is possible in regular c# application development.
However in SharePoint we can do the batch update of list items using CAML script.
The CAML script needs to be generated for the items which needs to be updated as below.

Get the list items:
SPListItemCollection items = spList.Items;
Generate CAML Script:
StringBuilder methodBuilder = new StringBuilder();

string batchFormat = "" +
"{0}"; //{0}-methodFormat

string methodFormat = "" + //{0}-Unique Value for each Item
"{1}" + //{1}-List Guid
"Save" +
"{2}" + //{2}-List ItemID
"{4}" + //{3}-Column Name, {4}-Column Value
"";

// Build the CAML update command script.
foreach (SPListItem item in items)
{
    //get the custom column value
    string customColumnValue = string.Empty;
    if (null != item["CustomColumnName"])
        customColumnValue = item["CustomColumnName"].ToString();
    
    //check whether custom column is empty
    if (string.IsNullOrEmpty(customColumnValue))
    {
        methodBuilder.AppendFormat(methodFormat, item.ID, item.ParentList.ID, item.ID, "CustomColumnName", "New Updated Value");
    }
}

//batch update script.  
string batchUpdateScript = string.Format(batchFormat, methodBuilder.ToString());
Execute CAML Script:
spWeb.ProcessBatchData(batchUpdateScript);

Similarly batch deleting script can also be generated. Look at the detailed post here for code.

Tuesday, December 20, 2011

JavaScript Find Absolute Position of element

Scenario: Get coordinates of a element (X, Y) to display overlay message immediate next or immediate below the element.
Based on the coordinates set the absolute position of the control (overlay) to display it accordingly. The overlay can be started any side/corner of the element.

Get the element object using JavaScript:
var obj = document.getElementById("controlelement");
Get the position of the element from Left
function findPosLeft(obj) 
{
    var posLeft = 0;
    if (obj.offsetParent) 
    {
        while (obj.offsetParent) 
        {
            posLeft += obj.offsetLeft;
            obj = obj.offsetParent;
        }
    }
    else if (obj.x) 
    {
        posLeft += obj.x;
    }

    return posLeft;
}
Get the position of the element from Top
function findPosTop(obj) 
{
    var posTop = 0;
    if (obj.offsetParent) 
    {
        while (obj.offsetParent) 
        {
            posTop += obj.offsetTop;
            obj = obj.offsetParent;
        }
    }
    else if (obj.y) 
    {
        posTop += obj.y;
    }
    return posTop;
}
Get the position of the element from Bottom
function findPosBottom(obj) 
{
    var posBottom = 0;
    if (obj.offsetParent) 
    {
        posBottom += obj.offsetHeight;
        while (obj.offsetParent) 
        {
            posBottom += obj.offsetTop;
            obj = obj.offsetParent;
        }
    }
    else if (obj.y) 
    {
        posBottom += obj.y;
        posBottom += obj.height;
    }
    return posBottom;
}
Get the position of the element from Right
function findPosRight(obj) 
{
    var posRight = 0;
    if (obj.offsetParent) 
    {
        posRight += obj.offsetWidth;
        while (obj.offsetParent) 
        {
            posRight += obj.offsetLeft;
            obj = obj.offsetParent;
        }
    }
    else if (obj.x) 
    {
        posRight += obj.x;
        posRight += obj.width;
    }
    return posRight;
}

JQuery Find Absolute Position of element

Scenario: Get coordinates of a element(X, Y) to display overlay message immediate next or immediate below the element.
Based on the coordinates set the absolute position of the control (overlay) to display it accordingly. The overlay can be started any side/corner of the element.

Get the element object using JQuery:
var obj = $('[id$=controlelement]');
Get the position of the element from Left
function findPosLeft(obj) 
{
    var pos = obj.offset();
    var left = pos.left;
    return left;
}
Get the position of the element from Top
function findPosTop(obj) 
{
    var pos = obj.offset();
    var top = pos.top;
    return top;
}
Get the position of the element from Bottom
function findPosBottom(obj) 
{
    var pos = obj.offset();
    var top = pos.top;
    var height = obj.height();
    var bottom = top + height;
    return bottom;
}
Get the position of the element from Right
function findPosRight(obj) 
{
    var pos = obj.offset();
    var left = pos.left;
    var width = obj.width();
    var right = left + width;
    return right;
}

SharePoint Check Memory Leaks in Custom Solution Development

In any SharePoint custom solution development, it is very important to make sure there are no memory leaks in the code. If there are any memory leaks the performance will be down and might face unnecessary issues at run-time.
While developing the code every developer ensures that SPSite and SPWeb objects are disposed either way (using clause or dispose method). But in a bigger solutions there are always chances for missing them in manual verification.

How good if there is a tool available to verify whether our solution (code) has any memory leaks, which can be checked in seconds of time. Yes there is a tool for the same. You can download it from SPDisposeChecker.

Even you can make this Tool as part of your visual studio Tools. Follow the simple 3 steps.

SharePoint Read Resource File Programatically

SharePoint custom solution development might requires some dynamic or configuration values. Generally the high level configurations can be stored in web.config(Ex: external connection string). But if there are more number of configurations required (Es: List columns, Content type names etc.,) we cannot store them in .config file as it is not safe.

So here the resource file comes into picture. Resource file is XML-Based file which holds the data in key-value pair. Resource file is generally used to store huge configurations for re-usability & consistency and Localization.

Resource file (.resx) should be added to 12\Resources directory in the solution as a new item.
The name format is SampleResourceFile.en-US.resx

Usage:
If the solution provides provisioning of lists or libraries with multiple columns programatically using either code or xml, All the column names can be stored in Resource file as a Key-Value pair.

Read Resource File: XML
The resource value for a key can be read in XML as below.
Read Resource File: C# Code
The resource value for a key can be read in c# as below.
string customColumnNameKey = SPUtility.GetLocalizedString("$Resources:CustomColumnNameKey", SampleResourceFile, (uint)CultureInfo.CurrentCulture.LCID); //LCIT is current local languare
To read the resource file programatically, a common wrapper class can be created to read the resource file throughout the solution by passing the key.
public class Resources
{
    /// Resource File Name.
    /// Filename can be configured in web.configured or can be used as constant.
    private const string RESOURCE_FILE_NAME = "SampleResourceFile";

    /// Method to get the singleton instance.
    public static string GetValue(string key)
    {
        return SPUtility.GetLocalizedString("$Resources:" + key, RESOURCE_FILE_NAME, (uint)CultureInfo.CurrentCulture.LCID);
    }
}

string customColumnName = Resources.GetValue("CustomColumnNameKey");