| |
|
Creating SharePoint list view dynamically |
|
|
I am back with yet another interesting topic.
Interesting, for the people who are stuck and trying
hard to achieve the objective. May be boring, for those
who are working on something, who were never asked by
their bosses to play with the Views. I created this
solution because, I myself, got stuck once. Let me
explain the problem. The problem (requirement) was to
filter the view dynamically. What? That's easy! I knew
you would say that. Filters can only be applied on a
single field or a field that contains a text value. If I
ask you to filter a view based on a column "Country",
this column is a promoted column. It was promoted from
an InfoPath form. The column itself was a repeating
table inside the InfoPath form. If you know what I am
talking about, then you know that repeating tables
cannot be promoted as a field in SharePoint. I promoted
the repeating table as a comma separated single value
(If you want to know how, send me an email). Again the
problem remains because filter cannot be applied on a
field or column that has comma or a dot or whatever. I
know its confusing. Let me give you an example. There is
a SharePoint library called "Lib A" that has a column
called "Country". It has two values, in fact, one value
separated by a comma. The value is "USA". I am in
another SharePoint site that has a link. The link simply
points to the "Lib A" library. The link opens a filtered
view of the library "Lib A". How do you do that? This is
a separate question but I will give the answer here. You
pass the filter in the URL. Because you are applying a
filter dynamically, you will create the link to open the
library "Lib A" dynamically also. Here is the code:
|
string link =
"http://server/User%20Registration/Forms/AllItems.aspx?SourceType=Country=&FilterField1={"
+ filter + "}&FilterValue1=USA"); |
"SourceType=" is "Country" field. "FilterField1" is a
GUID value of "Country" field. "FilterValue1" is the
value that will be searched upon. We have passed "USA"
as the parameter to this variable. This link will open a
filtered view of the library and only items that have
country as "USA" will be shown. So the question is from
where do we get the GUID of the "Country" column. Here
is the code to get the GUID:
SPSite site = SPContext.Current.Site;
SPWeb web = site.OpenWeb();
SPList list = web.Lists["Conntries"];
SPFieldCollection fldCollection = list.Fields;
string filter = Convert.ToString(fldCollection["Country"].Id); |
Cool. This link will show you a filtered view. Let's get
back to the original problem. This approach worked
because the Country contained a single value, something
like USA or UK or Mexico but the approach would fail if
the field had a value like "USA, UK, Mexico" The filter
won't work in that scenario and the approach would fail.
So the solution to this problem is to create a filtered
view dynamically and clicking the link will open the
newly created view. Note the difference in the two
approaches. The first one is not creating a new view.
It's applying a filter on an already created view. The
second approach create a filtered view dynamically and
then open that view. The second approach helps for the
scenarios where a field has multiple values. As I said,
I had a requirement once which involved promoting a
repeating table and applying filter on that. The second
approach gave me a perfect solution. The code to create
the filtered view is as following:
SPSite site = SPContext.Current.Site;
SPWeb web = site.OpenWeb();
SPList list = web.Lists["Countries"];
string CountryName = "USA";
SPViewCollection oViewCollection = list.Views;
int iExistingViews = list.Views.Count + 1;
string strViewName = "FilteredView" +
iExistingViews;
System.Collections.Specialized.StringCollection
viewFields =
new
System.Collections.Specialized.StringCollection();
viewFields.Add("Type");
viewFields.Add("First Name");
viewFields.Add("Last Name");
viewFields.Add("Address");
viewFields.Add("Zip");
viewFields.Add("City");
viewFields.Add("State");
viewFields.Add("Country");
viewFields.Add("Phone");
viewFields.Add("Fax");
viewFields.Add("Web");
string query = "<Where><Contains><FieldRef
Name=\"Country\"/>" +
"<Value Type=\"Text\">" + CountryName +
"</Value></Contains></Where>";
oViewCollection.Add(strViewName, viewFields,
query, 100, true, false);
web.Update();
string link = web.Url + "/" + list.Title +
"/Forms/" + strViewName + ".aspx
|
That's it. This code will generate a link that will open
the newly created view with a list of filtered items.
The code is simple and self explaining. I will explain
the logic briefly. "iExistingViews" contains the count
of existing view in the library. We increment it by 1
and use it to give a name to our new view. So if you
decide to name the view as "FilteredView", you can
append the count + 1 to give the view a unique name.
This is to make sure that view is not created with the
name that already exists. So we append "FilteredView"
with the count of existing views plus 1. If existing
count is 2, the new name will be "FilteredView3". It's
up to you which fields you want to show in the view. I
included all the fields of the "user registration"
library. "CountryName" variable contains "USA" (for
testing). The following line adds the view:
|
oViewCollection.Add(strViewName, viewFields,
query, 100, true, false); |
The fourth parameter in the above function represents
the number of items to show in the view. The link that
is created in the end will open the filtered view of the
library.
|
|
|