Friday, March 29, 2013

JavaScript Object Oritented Programming Vs C# (C++, Java)


JavaScript's OOP model is very different from C# or C++, Java. If you are from a background of C#(Java) programmer, it would take a while to really understand and get used to the OOP concepts in JavaScript.

At first glance when you study the object, class and inheritance in JavaScript, they all looks very familiar and you think you could understand them easily but you may not.

One thing that took me quite a while to really understand is that in JavaScript there is no real "Class". (or in other words, the Class in JavaScript is very different from C#).

Another thing that can help you understand OOP in JavaScript is that JavaScript is very "Object Centric" vs C# is "Class Centric".

With C#, you start programming by defining "Classes" and create inheritance among "Classes". In JavaScript, you usually start with defining "Objects" and create inheritance between "Objects". "Class" in JavaScript is really just a special function called "Constructor" (another familiar concept but it is very different).

A third thing that can help your understanding is that almost everything in JavaScript is "Object", object is object, function is object, class is function so it is object, namespace is function so it is object, string is object, array is object, ...

Class in C#

using System;
public class Dog
{
    private string face, color, leg;
    public Dog(string face, string color, string leg)
    {
        this.face = face;
        this.color = color;
        this.leg = leg;
    }
 
    public virtual string Run()
    {
        return face + color + leg + " is running";
    }
 
    public string Name
    {
        get
        {
            return "Dog";
        }
    }
}
 
public class GoldenRetriever : Dog
{
    public GoldenRetriever(string face, string color, string leg): base(face, color, leg)
    {   
    }
 
    public override string Run()
    {
        return "Gollden Retriever " + base.Run();
    }
}
 
class Program
{
    static void Main(string[] args)
    {
        //Create an instance of Dog
        Dog myDog = new Dog("^_^""""# # # #");
        Console.Write(myDog.Run());
 
        //Create an instance of golden retriever
        GoldenRetriever myGoldenRetriever = new GoldenRetriever("^_^""yellow""@ @ @ @");
        Console.Write(myGoldenRetriever.Run());
    }
}
 
The C# example shows that in C#, you starts with define a class "Dog" then define another class "GoldenRetriever" inherits from it. After both classes are defined, you can create objects from them. So in C#, you say "GoldenRetriever" inherits from "Dog". They are all classes. You don't say "myGoldenRetriever" inherits from "myDog", since they are all objects.

However, in JavaScript you do say that "myGoldenRetriever" inherits from "myDog", since in JavaScript "myDog" is used as template to create another object "myGoldenRetriever". Inheritance happens between objects than classes.

Class in JavaScript

Actually it is easier to think JavaScript without thinking about class. In JavaScript when mentioning "Class", you are just mentioning a function which plays the role of constructor of object. In my opinion JavaScript is a "Object Oriented Lanuage" without "Class".

1. Create a "Class".

        // Dog class constructor
        function Dog(face, color, leg) {
            this.face = face; // smily face
            this.color = color;
            this.leg = leg; // four legs
        }
        Dog.prototype = {
            run: function () { return this.face + this.color + this.leg + " is running ..." },
            // object properties added in prototype
            name: "Dog"
        }

2. Create an object from the "Class".

            var myDog = new Dog("^_^""""# # # #");
 
            ShowMessage2("run 1:" + myDog.run());
            ShowMessage2("run 1:" + myDog.face);
 
3. Create an inherited object from another object using ECMAScript 5.
 
            var myGoldenRetriever1 = Object.create(myDog);
            myGoldenRetriever1.face = "^...^";
            myGoldenRetriever1.color = "yellow";
            ShowMessage2("run 2:" + myGoldenRetriever1.run());
            ShowMessage2("run 2:" + myGoldenRetriever1.color);
 
 4. Create an inherited object from another object without ECMAScript 5

        // Create new GoldenRetriever object inheriting from dog
        function CreateGoldenRetriever(dog) {
            // GoldenRetriever class constructor
            function GoldenRetriever() { };
            GoldenRetriever.prototype = dog;
            return new GoldenRetriever();
        }

            var myGoldenRetriever2 = CreateGoldenRetriever(myDog);
            myGoldenRetriever2.face = "^...^";
            myGoldenRetriever2.color = "golden";
            ShowMessage2("run 3:" + myGoldenRetriever2.run());
            ShowMessage2("run 3:" + myGoldenRetriever2.face);

5. Create an inherited object from another object without ECMAScript 5 in more generic way.

        // inherit() returns a newly created object that inherits properties from the
        // prototype object p. It uses the ECMAScript 5 function Object.create() if
        // it is defined, and otherwise falls back to an older technique.
        function inherit(p) {
            if (p == nullthrow TypeError(); // p must be a non-null object
            if (Object.create) // If Object.create() is defined...
                return Object.create(p); // then just use it.
            var t = typeof p; // Otherwise do some more type checking
            if (t !== "object" && t !== "function"throw TypeError();
            function f() { }; // Define a dummy constructor function.
            f.prototype = p; // Set its prototype property to p.
            return new f(); // Use f() to create an "heir" of p.
        }

            var myGoldenRetriever3 = inherit(myDog);
            ShowMessage2("run 4:" + myGoldenRetriever3.run());
            ShowMessage2("run 4:" + myGoldenRetriever3.face);

As you can see in any of aboves ways to do inheritance in JavaScript, a new object is created and inherites from an existing object "myDog". "myGolenRetreiver" inherits from "myDog" but it is not a "sub class" of "myDog" since they are all objects.

In JavaScript it is possible to introduce the concept of "sub class", the "sub class" in JavaScript is a way to create contructor function based on another contructor function. It is more advanced topic and I am not sure how practical to use it in the real world.

Here are few good articles that explains "prototype" in details.

http://msdn.microsoft.com/en-us/magazine/ff852808.aspx

http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/

http://net.tutsplus.com/tutorials/javascript-ajax/prototypes-in-javascript-what-you-need-to-know/
 
 
 
 
 
 
 

Wednesday, March 20, 2013

Connect PerformancePoint Filter Web Part and Analytic Report Web Part

Programmatically Connect PerformancePoint Filter Web Part and Analytic Report Web Part

Reference:
 
http://stackoverflow.com/questions/1048736/web-part-connections-in-site-definitions
http://social.technet.microsoft.com/Forums/en-US/ppsmonitoringandanalytics/thread/992fa91d-6587-479c-aacf-13d789332231/
 
MSDN has good code samples on how to create PerformancePoint content such filters, KPI, scorecard and reports at http://msdn.microsoft.com/en-us/library/ee570773.aspx
 

Here is the code about how you can set up the connection between a filter web part and a report view web part.


        private static void SetWebPartConnections(SPWeb web, string pageUrl)
        {
            SPFile file = web.GetFile(pageUrl);
            if (file == null && !file.Exists)
                return;
 
            if (file.CheckOutType != SPFile.SPCheckOutType.None)
                file.CheckIn("");
 
            file.CheckOut();
 
            try
            {
                SPLimitedWebPartManager webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
                if (webPartManager == null)
                    return;
 
                ReportViewWebPart reportView = null;
                Microsoft.PerformancePoint.Scorecards.WebControls.FilterWebPart dateFilter = null;
                foreach (System.Web.UI.WebControls.WebParts.WebPart wp in webPartManager.WebParts)
                {
                    if (!string.IsNullOrEmpty(wp.Title) && wp.Title == "BI Chart")
                    {
                        reportView = wp as ReportViewWebPart;
                        continue;
                    }
 
                    if (!string.IsNullOrEmpty(wp.Title) && wp.Title == "BI Date Filter")
                    {
                        dateFilter = wp as FilterWebPart;
                        continue;
                    }
                }
 
                SPWebPartConnection connection = new SPWebPartConnection();
                connection.ID = "pps_connection_abc123";
                connection.ConsumerConnectionPointID = "BIDataProvider";
                connection.ProviderConnectionPointID = "TransformableBIDataProvider";
                connection.ConsumerID = reportView.ID;
                connection.ProviderID = dateFilter.ID;
 
                
                TransformProviderConsumerRecord transformRecord = new TransformProviderConsumerRecord();
                transformRecord.ConsumerParameterName = "[Dim Time].[GenericTime]";
                transformRecord.DisplayColumnName = "DisplayValue";
                transformRecord.EncodeAsSet = false;
                transformRecord.MappingId = Guid.NewGuid().ToString();
                transformRecord.ProviderParameterDisplayName = "PerformancePoint Values";
                transformRecord.ProviderParameterName = "FilterValues";
                transformRecord.TypeFullName = "System.String";
                transformRecord.ValuesColumnName = "MemberUniqueName";
 
                List<TransformProviderConsumerRecord> list = new List<TransformProviderConsumerRecord>();
                list.Add(transformRecord);
                ProviderConsumerTransformations transformations = new ProviderConsumerTransformations(list);
 
                // Build TransformConditionalVisibilityRecord
                TransformConditionalVisibilityRecord visibilityRecord = new TransformConditionalVisibilityRecord();
                visibilityRecord.IsDefaultVisibility = false;
                visibilityRecord.IsDefined = false;
 
                // Build TransformerConfigurationRecord
                TransformerConfigurationRecord configurationRecord = new TransformerConfigurationRecord(transformations, visibilityRecord);
 
                TransformableBIDataProviderTransformer transformer = new TransformableBIDataProviderTransformer();
                transformer.ConfigurationState = configurationRecord;
 
                // Set connection's transformer
                connection.SPTransformers.Add(transformer);
 
                webPartManager.SPWebPartConnections.Add(connection);
                webPartManager.SaveChanges(reportView);
                webPartManager.SaveChanges(dateFilter);
            }
            catch (Exception expt)
            {
                string message = expt.Message;
            }
            finally
            {
                file.CheckIn("");
            }
        }

Sunday, March 17, 2013

Build A Custom Calendar Web Part for SharePoint 2010

Reference:

http://jerryyasir.wordpress.com/2009/10/12/using-asp-calendar-control-to-show-sharepoint-events/

http://www.codeproject.com/Articles/78532/Event-Calendar-Listing-Web-Part-SharePoint-2010

Project:

A calendar web part which will show monthly events in a compact view with a list of all monthly events under the calendar.

Since neither the OOTB SharePoint calendar nor any existing online solutions can meet our requirements, I decided to build a custom calendar web part using ASP.NET calendar control.

As you can see from the following screenshots which were taken from the finished portal site, the date with events are highlighted in the monthly view. The event list under the web part shows all events in the current monthly view of the calendar.
 
When user mouses over any specific day in the calendar, the day will be highlighted with different color. When user clicks on the date, if there are any events for that day, the event list will be filtered to show only events from that day.


When user navigants to the other month, the caledar view will change accordingly.

Clicking on "Add an event" and any event in the event list will trigger a modal dialog window which will let user to add a new event or view the event just as working with the OOTB calendar.


Implementation:

The calendar web part is implemented using Visual Studio 2010 visual web part.

The ascx file contains the ASP.NET calendar control and a literal control for the event list.

<asp:Calendar ID="SPCalendar" CssClass="ECal" TitleStyle-CssClass="ECalTitle" TodayDayStyle-CssClass="ECalToday" OtherMonthDayStyle-ForeColor="#AAAAAA" TodayDayStyle-BackColor="#F6F4CC" DayStyle-ForeColor="#676767" runat="server" OnDayRender="SPCalendar_DayRender" OnSelectionChanged="SPCalendar_SelectionChanged" OnVisibleMonthChanged="SPCalendar_VisibleMonthChanged">
        </asp:Calendar>


<asp:Literal ID="EventList" runat="server"></asp:Literal>

Query the Calendar List

The most noticeable differences between querying a ordinary list and a SharePoint calendar list is the query. The CAML query used to query a calendar list has difference syntax. Using the ordinary CAML query to query a calendar list may not cover the special situation such as recurrence events.


     SPWeb web = SPContext.Current.Site.RootWeb;
            SPList calendarList = web.Lists.TryGetList(WebPart.EventListName);
            if (calendarList == null)
                throw new SPException("Events list is not found");
 
            SPQuery query = new SPQuery();
            query.ExpandRecurrence = true;
            query.CalendarDate = dateTime;
            query.Query = @"
<Where>
    <DateRangesOverlap>
        <FieldRef Name='EventDate' />
        <FieldRef Name='EndDate' />
        <FieldRef Name='RecurrenceID' />
        <Value Type='DateTime'><Month /></Value>
    </DateRangesOverlap>
</Where>
<OrderBy><FieldRef Name='EventDate' Ascending='True' /></OrderBy>
";
            query.ViewFields = "<FieldRef Name=\"EventDate\" /><FieldRef Name=\"EndDate\" /><FieldRef Name=\"Title\" />";
 
            SPListItemCollection items = calendarList.GetItems(query);
            int count = 0;
            if (items.Count > 0)
            {
                foreach (SPListItem item in items)
                {...
The above query gets all events for the current monthly view which includes a few days from the previous month and a few days from next months.
To get the events for a particular day, use this query

            query.Query = @"
<Where>
    <DateRangesOverlap>
        <FieldRef Name='EventDate' />
        <FieldRef Name='EndDate' />
        <FieldRef Name='RecurrenceID' />
        <Value Type='DateTime'><Today /></Value>
    </DateRangesOverlap>
</Where>
<OrderBy><FieldRef Name='EventDate' Ascending='True' /></OrderBy>
";
After querying the calendar list for events, save the event's start date and end day in a data structure such as List<KeyValuePair<DateTime, DateTime>> eventsInMonth; for use when render the day's background color in the "DayRender" event of the ASP.NET calendar.

Implement the following ASP.NET calendar events to render the calendar and update the calendar corresponding to different events such as when using clicking on a date or navigating to next month.
protected void SPCalendar_DayRender(object sender, DayRenderEventArgs e)
{}
protected void SPCalendar_SelectionChanged(object sender, EventArgs e)
{}
protected void SPCalendar_VisibleMonthChanged(object sender, MonthChangedEventArgs e)
{}
Happy SharePointing!
Do's and Don't's in SharePoint Programming (draft)
 
 
 1. Use SPWeb.Lists.TryGetLists("ListName")



SPList list = web.Lists.TryGetList("List Name");
if (list != null)
{
     ...
}

Don't use SPWeb.Lists["ListName"] which will throw exception when list with the name doens't exists.

2. Don't dispose your current context!
 
Don't do this

using (SPContext.Current.Web)
{
    ...
}
 
or
 
SPWeb web = SPContext.Current.Web;
using (web)
{
    ...
}
 
Otherwise you will see errors.


3. Always use _spBodyOnLoadFunctionNames and ExecuteOrDelayUntilScriptLoaded together and avoid using jQuery $(document).ready(function() {...}); or JavaScript windows.load = function() { ...};

        if (ExecuteOrDelayUntilScriptLoaded && _spBodyOnLoadFunctionNames) {
            _spBodyOnLoadFunctionNames.push(ExecuteOrDelayUntilScriptLoaded(initSaveMenu, "sp.js"));
        }




 
 
Connect Text Filter to List View with Wildcard Support



In a recent project, we were trying to add search/filter funcationality to a page to support search/filter a list view (XsltListViewWebPart). This is different from the SharePoint "Search", which will search either the entire site or a list and return the results in a search result page.

What we need is a search or filter that will search certain text in a list and make the list to show only items that match. After the search, user should be able to select the items in the list and trigger some actions on them.

The easiest way to achieve this is to use SharePoint Text Filter web part and connect it to a column in the XsltListViewWebPart. However this filter can only do exact match which make it not very useful as a search tool.

To have a Text Filter that can do wild card match or partial string match manually through SharePoint Designer, you can reference this link

http://coolsharepoint.blogspot.com/2012/03/sharepoint-2010-configure-textfilter-to.html#!/2012/03/sharepoint-2010-configure-textfilter-to.html

Another limit of Text Filter is that it can only connect to one column in the list, to do a search on multiple columns you can reference this article

http://gustavogarciadotnet.blogspot.com/2011/01/sharepoint-list-filter-wildcard-search.html

What I am going to show here is how to do all these programmatically. I didn't find anyone else have done this before. I did all these by reverse engineering what the SharePoint Designer does.



public static void SetTextFilterAndXsltViewWebPartConnection(SPWeb web, string pageUrl, string filterWebPartName, string gridWebPartName)
{
    SPFile file = web.GetFile(pageUrl);
    if (file == null && !file.Exists)
        return;
 
    if (file.CheckOutType != SPFile.SPCheckOutType.None)
        file.CheckIn("");
 
    file.CheckOut();
 
    try
    {
        SPLimitedWebPartManager webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
        if (webPartManager == null)
            return;
 
 
        System.Web.UI.WebControls.WebParts.WebPart filterwp = null;
        XsltListViewWebPart xsltwp = null;
 
        foreach (System.Web.UI.WebControls.WebParts.WebPart wp in webPartManager.WebParts)
        {
            if (!string.IsNullOrEmpty(wp.Title) && wp.Title.ToLower() == filterWebPartName.ToLower())
            {
                filterwp = wp;
                continue;
            }
 
            if (!string.IsNullOrEmpty(wp.Title) && wp.Title.ToLower() == gridWebPartName.ToLower())
            {
                xsltwp = wp as XsltListViewWebPart;
                continue;
            }
        }
 
        SPWebPartConnection connection = new SPWebPartConnection();
        connection.ID = "custodianFilterConnection";
 
        connection.ConsumerConnectionPointID = "DFWP Parameter Consumer ID";
        connection.ConsumerID = xsltwp.ID;
 
        connection.ProviderConnectionPointID = "ITransformableFilterValues";
        connection.ProviderID = filterwp.ID;
 
        TransformableFilterValuesToParametersTransformer searchTransformer = new TransformableFilterValuesToParametersTransformer();
        searchTransformer.ConsumerFieldNames = new string[] { "SearchQuery" };
        searchTransformer.ProviderFieldNames = new string[] { "Search" };
 
        connection.SPTransformers.Add(searchTransformer);
 
        webPartManager.SPWebPartConnections.Add(connection);
 
        webPartManager.SaveChanges(xsltwp);
        webPartManager.SaveChanges(filterwp);
 
    }
    catch (Exception expt)
    {
        Console.WriteLine(expt.Message + expt.StackTrace);
    }
}
To have this solution work, there is another hurdle to overcome. You need to create the a view in the XsltListViewWebPart as described in my previous bloghttp://ethandeng.blogspot.com/2012/12/define-list-view-for.html
 

public static void SetXsltListViewCustomterView(SPWeb web, SPView view)
{
    //Create view
    //http://sarangasl.blogspot.com/2009/12/create-sharepoint-list-view.html
    string viewQuery = "<OrderBy><FieldRef Name=\"fullname\" /></OrderBy><Where><Contains><FieldRef Name=\"SearchableText\"/><Value Type=\"Text\">{SearchQuery}</Value></Contains></And></Where>";
            
    view.Query = viewQuery;
    view.ViewFields.DeleteAll();
    view.ViewFields.Add("fullname");
    view.ViewFields.Add("company");
    view.ViewFields.Add("status");
    view.ViewFields.Add("noticeTitle");
 
    view.Paged = true;
    view.RowLimit = 3;
    view.DefaultView = true;
 
    view.Update();
}

Reference:
http://stackoverflow.com/questions/1048736/web-part-connections-in-site-definitions





Build Custom SharePoint Grid View Web Part with Sorting, Filtering and Pagination

 
There are many situations in SharePoint development that demand a custom grid view instead of using the XsltListViewWebPart and do transform on it. These situation includes

1. External data source. The application needs to present data from external data source such as database.

2. Aggregated view of data. The data that need to be presented are not a simple view into one list but an aggregated view of data from more than one SharePoint lists.

3. A complex data presentation. If you need to present data in a complex web part such as a tabbed view of different lists. You cannot reuse XsltListViewWebPart inside your web part (There is no webpart inside webpart. Web Part can only be added to a web part zone on a page), you have to use SPGridView to rebuilt the list view.

After Googling for a few hours, I found I can achieve my goal without writing a single line of C# code. SharePoint had built all the parts for you but it is just a hidden treasure of SharePoint that Microsoft doesn't care to let you know.

The final built POC web part looks like this



As highlighted, the web part supports Sorting, Pagination and Filtering.

Here is the HTML from the ascx file of the SharePoint visual web part. Notice that there are no code behind in this solution.




<asp:SqlDataSource
    ID="SqlDataSource1"
    runat="server"
    SelectCommand="select FirstName, LastName,he.JobTitle, he.HireDate from Person.Person pp join HumanResources.Employee he on pp.BusinessEntityID = he.BusinessEntityID" 
    ConnectionString="Data Source=.;Initial Catalog=AdventureWorks2008R2;Persist Security Info=True;User ID=sql_Service;Password=***********" 
    ProviderName="System.Data.SqlClient">
</asp:SqlDataSource>
 
<SharePoint:SPGridView
    ID="GridView1"
    runat="server"
    DataSourceID="SqlDataSource1"
    AutoGenerateColumns="False"
    EnableModelValidation="True"
 
    AllowPaging="True"
    PageSize="5"
    
    AllowSorting="True"
    
    AllowFiltering="true"
    FilterDataFields="FirstName,LastName,JobTitle,HireDate"
    FilteredDataSourcePropertyName="FilterExpression"
    FilteredDataSourcePropertyFormat="{1} like '{0}'"    
    >
 
    <Columns>
        <asp:BoundField DataField="FirstName" HeaderText="FirstName"
            SortExpression="FirstName" />
        <asp:BoundField DataField="LastName" HeaderText="LastName" 
            SortExpression="LastName" />
        <asp:BoundField DataField="JobTitle" HeaderText="JobTitle" 
            SortExpression="JobTitle" />
        <asp:BoundField DataField="HireDate" HeaderText="HireDate" 
            SortExpression="HireDate" />
    </Columns>
 
</SharePoint:SPGridView>
 
<SharePoint:SPGridViewPager runat="server" GridViewId="GridView1" />

To have this solution works, there are a few things you need to pay attention to.

First, the AutoGenerateColumns must be set to "False" and you must use BoundField to explicitly declare the columns. Otherwise you will see this error in log file

System.InvalidOperationException: This derived class does not allow AutoGenerateColumns to be true. You must specify each of the columns using BoundField, TemplateField, or other compatible class.

Second, by default the pagination of the SPGridView is hidden. This is done on purpose since SharePoint uses SPGridViewPager control to show the pages. If you have next code, the SPGridView pagination will show but you don't want to do this. SPGridViewPager is a better choice to give you the OOTB user experience.

protected void Page_Load(object sender, EventArgs e)
{
    GridView1.PagerTemplate = null;
}
Third, you must turn on the filtering as shown in the code and there are not much documenation elsewhere to show you how to do it.

Update:

If you are using "DataKeyNames" in the SPGridView, make sure the field is a text field. You will have error if the field is not a text field such as  guid value.



DataKeyNames="customerGuid"

Unexpected System.InvalidCastException: Unable to cast object of type 'System.Guid' to type 'System.String'.    at Microsoft.SharePoint.WebControls.SPGridView.set_PageIndex(Int32 value)     at Microsoft.SharePoint.WebControls.SPGridViewPager.OnClickNext(EventArgs args)     at Microsoft.SharePoint.WebControls.SPGridViewPager.RaisePostBackEvent(String eventArgument)     at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)     at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 2c6d51c4-34bf-47b9-8687-ddaf4266ef24
see: http://stackoverflow.com/questions/3386450/paging-error-using-spgridview

References:

http://www.reversealchemy.net/2009/05/24/building-a-spgridview-control-part-2-filtering/
http://www.codeproject.com/Articles/35536/Creation-of-a-SPGridview-Webpart-having-Pagination
http://ketulpatel.wordpress.com/2008/06/06/custom-paging-in-spgridview-extending-spgridviewpager/
http://books.google.com/books?id=4lKnn9ZzG1AC&printsec=frontcover#v=onepage&q&f=false
http://books.google.com/books?id=4lKnn9ZzG1AC&pg=PA701&lpg=PA701&dq=SPGridView+AllowFiltering+FilterDataFields+FilteredDataSourcePropertyName&source=bl&ots=LR4uKwlTBq&sig=erwxMAk20C4KZNjCuwIYm1pgIeo&hl=en&sa=X&ei=zc3YUN6OFK3BiwKml4CIBw&ved=0CEAQ6AEwAg#v=onepage&q=SPGridView%20AllowFiltering%20FilterDataFields%20FilteredDataSourcePropertyName&f=false
Define the List View for XsltListViewWebPart

When you add XsltListViewWebPart to your page, you will have needs to define the proper list view for the XsltListViewWebPart.

There are two ways you can define the list view for a XsltListViewWebPart programmatically.

First, you can reference to an existing list view of the list from the XsltListViewWebPart. Second, you can use a reflection to change the SPView object currently associated with the XsltListViewWebPart. This is more or less a hack since SharePoint doesn't expose the list view object as public property.

The first step is to get the XsltListViewWebPart from the page using SPLimitedWebPartManager

SPLimitedWebPartManager webPartManager = file.GetLimitedWebPartManager(PersonalizationScope.Shared);
if (webPartManager == null)
  return;
 
foreach (System.Web.UI.WebControls.WebParts.WebPart wp in webPartManager.WebParts)
{
    // Only handle xslt web part
    XsltListViewWebPart xsltwp = wp as XsltListViewWebPart;
    if (xsltwp == null)
        continue;

The second step is to get the list and list view of the list.

 // Get list by listUrl
 // catch invalid list url exception
 try
 {
   list = web.GetList(webServerRelativeUrl + "/" + listUrl);
   view = list.Views[viewName];
 }
 catch (Exception expt)
 {
   EventLogger.LogError("SetXsltWebPartView:" + expt.Message + expt.StackTrace);
 }

The third step is to set and save the list view of the XsltListViewWebPart

// Must set ViewId and ViewGuid at the same time
xsltwp.ViewId = Int32.Parse(view.BaseViewID);
xsltwp.ViewGuid = view.ID.ToString("B");
 
webPartManager.SaveChanges(xsltwp);

This approach may not work for some XsltListViewWebPart, for example I found if the list is External List, this won't work. Another approach is to use reflection to get the "ContextView" property as SPView object and change the SPView object.

PropertyInfo pi = xsltwp.GetType().GetProperty("ContextView"BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
SPView view = (SPView)(pi.GetValue(xsltwp, null));
SetXsltListViewCustodianView(web, view);        
webPartManager.SaveChanges(xsltwp);


public static void SetXsltListViewCustomerView(SPWeb web, SPView view)
{
    //Create view
    //http://sarangasl.blogspot.com/2009/12/create-sharepoint-list-view.html
    string viewQuery = "<OrderBy><FieldRef Name=\"FirstName\" /></OrderBy>";
            
    view.Query = viewQuery;
    view.ViewFields.DeleteAll();
    view.ViewFields.Add("FirstName");
    view.ViewFields.Add("LastName");
    view.ViewFields.Add("JobTitle");
    view.ViewFields.Add("Company");
 
    view.Paged = true;
    view.RowLimit = 3;
    view.DefaultView = true;
 
    view.Update();
}

Happy SharePointing!
Program SharePoint Mulitple Item Selection in List View

Reference:
http://tomaszrabinski.pl/wordpress/2012/02/25/get-selected-list-items-sharepoint-2010/
http://programmers.stackexchange.com/questions/122357/how-should-data-be-passed-between-client-side-javascript-and-c-code-behind-an-a

This solution involes using SharePoint Client Object Model and jQuery ...

I recently worked on a project that required triggering server side code based on what user selects in a list view. A typical senario is a user select multiple customers from a contact list and send a emails to them with one click.

Just as OOTB of SharePoint, you can select more than one items in a list and click the "Delete Item" button in the ribbon to delete them all.


I need to implement this in a web part instead of add custom action to the ribbon since the portal site we developed won't show ribbon.

To implement this, I have both the XsltListViewWebPart and the custom "Actions" web part provisioned in a web part page.

The custom "Actions" web part is implemented as SharePoint visual web part and in the ascx file, it has

<script type="text/javascript">
 
     function CustomActionOnSelectedItem() {
        // get current client context
        var context = SP.ClientContext.get_current();
        var selectedItems = SP.ListOperation.Selection.getSelectedItems(context);
        var selectedList = SP.ListOperation.Selection.getSelectedList(context);
 
        var itemIds = "";
        for (i in selectedItems) {
            itemIds += selectedItems[i].id + ";";
        }
 
        var hiddenFieldId = '<%= HiddenField1.ClientID %>';
        $('#' + hiddenFieldId).val(selectedList + ":" + itemIds);
    }
 
 
 
</script>
 
<asp:HiddenField ID="HiddenField1" runat="server"/>
<asp:Button ID="btOK" runat="server" Text="OK" OnClientClick="CustomActionOnSelectedItem()" onclick="btOK_Click" Width="133px" />
The JavaScript use sSharePoint Client Object Model to get the list ID and the selected item IDs and pass the information to server side through ASP.NET HiddenField control.

One trick to notice is to get the ASP.NET control client side  ID by using inline .NET code



var hiddenFieldId = '<%= HiddenField1.ClientID %>';
If you are not going to have the JavaScript directly in the ascx file and loading it from a seperate js file, then this trick will not work.

If this is the case, you can do the jQuery selection based on class name as

$('.MyHiddenField').val(itemIds);

However if you use this technique, you cannot use the ASP.NET HiddenField control since the it doesn't support "CssClass" attribute.

You can use the HTML input control instead but add runat="Server" to make sure the server side code can get its value.


<input ID="HiddenField1"  type="hidden" runat="server" class="MyHiddenField"/>

The server side will be able to get the item ID as next



HashSet<Guid> itemGuidList = Utility.GetItemGuidList(HiddenField1.Value);

The "GetItemGuidList" is a custom utility method that will parse the item IDs from the string.
        public static HashSet<Guid> GetItemGuidList(string value)
        {
            HashSet<Guid> guidList = new HashSet<Guid>();
 
            if (string.IsNullOrEmpty(value))
                return guidList;
 
            string[] guids = value.Split(';');
            foreach (string idstr in guids)
            {
                try
                {
                    if (idstr == null || idstr.Trim().Length == 0)
                        continue;
                     
                    Guid guid = new Guid(idstr);
                    guidList.Add(guid);
                }
                catch (Exception expt)
                {
                    EventLogger.LogError("Invalid guid : " + idstr + " " + expt.Message);
                }
            }
 
            return guidList;
        }

Happy SharePointing!