Friday 30 November 2007

SharePoint: Paging your results in SPGridView

To get SharePoint to handle paging in your webparts which are using GridView (SPGridView) you need to do a few tweaks to your code:

Just above your grid.DataBind() you need to insert the following code:

// Turn on paging and add event handler
grid.PageSize = 10;
grid.AllowPaging = true;
grid.PageIndexChanging +=
new GridViewPageEventHandler(grid_PageIndexChanging);

then add the event handler:
void grid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
grid.PageIndex = e.NewPageIndex;
grid.DataBind();
}


If you are getting your the data set to bind to using a dynamic query, you might have a problem with the paging, since the state of the data set is not maintained. What was happening is that we we clicked on the next pages of the paging mechanism, the DataSet was lost, and thus all results in the GridView were lost. To maintain it, we stored the DataSet in the session, and this resolved our problem. I'm not sure whether is the right or the best solution, if anyone has better ideas please comment :)

Wednesday 28 November 2007

SharePoint - Search Customizations

Warning: we have drifted slightly from our initial aim of using only OOB functionality. We are actually writing code which uses the SharePoint object model. The Object model is too sweet to resist ;) and with small changes you can deliver fabulous results. The following is a post about using the KeyWord Query class to customize sharepoint search

KeywordQuery class:

This class offers quite an extensive range of functionality.

It is useful when you need to build advanced custom search webparts e.g. you have want the user to limit their searches to certain metadata only. To do this you create property mappings in the SharedServices search settings which map to the metadata you want to use in your search.

Then using the KeywordQuery class you can limit your search to certain properties only:

KeywordQuery query= new KeywordQuery("http://yourmosssite/");

Then using a dropdownlist or checkboxes with your lists of metadata you can create a search which limits the result to properties you have used. Let's say you want to limit to Author property

query.QueryText=textSearchBox.Text + "Author:'"+dropDownList.SelectedItem.Value+"'";

Another option is that you can create your own custom scopes, and then use these scopes to limit the search results:
query.HiddenConstraints="scope:" + "\"Customers\"";

Combining all the above options and creating a webpart with dropdowns and checkboxes you'l get very nicely customized searching in SharePoint focused exactly on your needs.

Thursday 15 November 2007

SharePoint 2007: Creating a custom advanced search webpart - Part 2

In the first part of this series of posts, we explained how to create a custom advanced search box by default which limits searches to a particular search scope.

In this part we will explain how to create a advanced search customization which uses a dropdown to limit results to a particular set of meta data / categories only.

Typical search requirements would be that users can limit their search results to a particular category of results only. An example of this would be the following: You have created a number a document library(ies) each having a DocType column which identifies whether the uploaded document is a Purchase Order, Invoice, Contract, Tender etc. You then want to create a search customisation such that your users can choose to search within Purchase Orders only.

This can be done using a number of sharepoint features and the advanced search custom webpart we will build.

Defining a searchable property

The first thing that we need to do is ensure that the DocType column we have created to categorize our documents is a searchable. To do this we need to go to the Shared Services > Search Settings > Metadata Property Mappings in Central Administration. As the description in this page says, "Users can perform queries over managed properties". Therefore we need to create our own mapped data property, and map this property to the DocType column we have created.

Click on the New Managed Property, give the property a name (DocType), and specify that this will be a text property. In the Mappings to crawled properties you need select the property to map to by clicking on Add Mapping and selecting the DocType column. This is done by searching for the DocType crawled property name. (If you don't find it here, you need to perform a full crawl, so that your column is discovered, and then re-do the steps here).

Once this is done you need to perform a full crawl again to make sure that the Number of items found with this property has a number which is greaten than zero. This means that items which use the DocType have been discovered.

Creating a custom advanced search dropdown which searches this property

Once again, we need to create a webpart page with a Content Editor Web Part and a Search Core Results web part. Using the source editor we define the following code:

The ASB_TextDT_Props defines the properties which will be used to define the text properties which will be used to build the query.

Quoting Tom Clarkson:

"ASB_TextDT_Props and ASB_DateTimeDT_Props Are lists separated by "#;#" which specify the properties which will be treated as text and datetimes respectively when building the query. All others are treated as numbers. "

Thus in our case:
<input type="hidden" name="ASB_TextDT_Props" id="Hidden4" value="DocType" />

We then define the search such that only items that contain certain values are displayed in the search using the following:

<input name="nameprefix$ASB_PS_plb_1" type="hidden" value="DocType" /> <input name="nameprefix$ASB_PS_olb_1" type="hidden" value="Contains" />

ASB_PS_plb_1 is the internal name of the property to search (in our case DocType)

whilst ASB_PS_olb_1 is the operator which will be used (contains)

The next thing is to actual build the drop down list:
<SELECT name="nameprefix$ASB_PS_pvtb_1"> <OPTION></OPTION>
<OPTION>Purchase Order</OPTION>
<OPTION>Invoice</OPTION>
<OPTION>Contract</OPTION>
<OPTION>Tender</OPTION>
</SELECT>

Once this is done, the only thing which is left is to create the text box to enter the queries to search for:
<input name="nameprefix$ASB_TQS_AndQ_tb" type="text" />

This used the ASB_TQS_AndQ_tb to define the All words in query operator.

The last thing which is required is the Submit button which posts to the CustomSearch.aspx page (which is the page which contains our Search Core Results Page):

<input type="hidden" name="nameprefix$ASB_SS_scb_1_4" value="nameprefix$ASB_SS_scb_1_4"/></table> <INPUT id="Submit1" onclick='WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("nameprefix$ASB_BS_SRCH_1", "", false, "", "/Pages/Pages/CustomSearch.aspx", false, false))' type="submit" name="nameprefix$ASB_BS_SRCH_1" value="Search" />

All Code:

<input type="hidden" name="ASB_TextDT_Props" id="Hidden4" value="DocType" />

<input name="nameprefix$ASB_PS_plb_1" type="hidden" value="DocType" /> <input name="nameprefix$ASB_PS_olb_1" type="hidden" value="Contains" />

<SELECT name="nameprefix$ASB_PS_pvtb_1"> <OPTION></OPTION>
<OPTION>Purchase Order</OPTION>
<OPTION>Invoice</OPTION>
<OPTION>Contract</OPTION>
<OPTION>Tender</OPTION>
</SELECT>

<input name="nameprefix$ASB_TQS_AndQ_tb" type="text" />

<input type="hidden" name="nameprefix$ASB_SS_scb_1_4" value="nameprefix$ASB_SS_scb_1_4"/></table> <INPUT id="Submit1" onclick='WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("nameprefix$ASB_BS_SRCH_1", "", false, "", "/Pages/Pages/CustomSearch.aspx", false, false))' type="submit" name="nameprefix$ASB_BS_SRCH_1" value="Search" />

This creates a dropdown custom advanced search which limits the search results to the particular category you have chosen. For more details on how this was done and what each operator does, what they stand for and more operations which you can use in your custom queries visit Tom Clarkson's post.

Sharepoint 2007: Creating a custom advanced search webpart - Part 1

Following the post about the Creating a custom advanced search box in moss 2007 article, I did a few customisations of my own.

So let's give a few examples of what can be done with this new toy:

Remember that you need to create a web part page, and add a Content Editor Web Part and a Search Core Results web part (as defined by the linked article).

1. Creating a search box limited to a single scope (without the user having to select the scope to limit too)
Typically you'll have clients who want advanced search capabilities limited only to certain lists only. The way we usually do this is to create a custom search scope and then enable the Scopes in the advanced search. This is ok but not good enough for some clients who want to make this capability transparent to the user. Therefore we create a custom advanced search which by default only limits results to a particular scope.

We need to add the following code to the Content Editor Web Part

<input name="nameprefix$ASB_TQS_AndQ_tb">
<input name="nameprefix$ASB_TQS_PhraseQ_tb">
<input name="nameprefix$ASB_TQS_OrQ_tb">

This codes will create the three text boxes which will give us:

  • Search All of these words
  • Exact phrase
  • Any of these words

respectively.

Next is the search scope limitation. This requires some more tinkering. First of all go to advanced search page which is available by default. Enable the scope picker in the Advanced Search Web part options. Then view the source of the page, and find the name of the search scope you want to limit to. This will be in a label which has should have end with a name similar to the following: ASB_SS_scb_x_x where each x is a number. In my case I have ASB_SS_scb_1_4.

This is the parameter we need to send to the search. Therefore you need to create a hidden input box with this parameter:

<input name="nameprefix$ASB_SS_scb_1_4" value="nameprefix$ASB_SS_scb_1_4" type="hidden" >

This will send this parameter automatically to the search instead of requiring the user to check the required scope checkbox.

The last thing to do is define the Search box and the postback to the page which will display the results.

Complete code:

<input name="nameprefix$ASB_TQS_AndQ_tb" type="text" /></td></tr><tr><td><input type="hidden" name="nameprefix$ASB_SS_scb_1_4" value="nameprefix$ASB_SS_scb_1_4"/>

<INPUT id="Submit1" onclick='WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("nameprefix$ASB_BS_SRCH_1", "", false, "", "/Pages/CustomSearch.aspx", false, false))' type="submit" name="nameprefix$ASB_BS_SRCH_1" value="Search" />

So here we are limiting your advanced search to a particular scope only. Part 2 will deal with creating a drop down to limit search results to particular metadata / categories only. For more details on how this was created, visit Tom Clarkson's post.


Monday 12 November 2007

Finding the SharePoint assembly: Microsoft.SharePoint.dll

When you are developing and you ned to add a Microsoft.SharePoint reference, you need to make sure that you know where the Microsoft.SharePoint.dll is. This and other dlls are found in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\ISAPI

Thursday 8 November 2007

Creating your own Advanced Search webpart in sharepoint 2007

Tom Clarkson is da man!


In the linked post, he gives a great example on how you can create your own custom advanced search box. The great thing about this is that not only can you add your own custom properties as shown in the post prior to this, but you can solve the question we asked in that same post, i.e. the question of actually having dropdowns to narrow down the search options to the user.

Using this, and creating custom search scopes, I think we have a very good playing field for creating highly customized searching capabilities.

Adding properties to the Advanced search webpart in SharePoint 2007

Jonathon's Blog: Searching Custom Column Values in MOSS 2007

Very detailed steps on creating custom properties in the advanced search. Lots of people here asking whether it would be possible to have a dropdown list with the choices available, such that the search options of the users are limited.

This is something I am highly interested in, so I'd be interested if someone posts a solution to this.

Wednesday 7 November 2007

Official Google Blog: It's not about the spam

Official Google Blog: It's not about the spam

Ever wondered how Gmail catches nearly all its Spam?

Thursday 1 November 2007

SharePoint WorkFlow Link Dump

Workflow and ASPX forms
http://blogs.msdn.com/sharepoint/archive/2006/12/19/what-about-workflow-and-aspx-forms.aspx

SharePoint 2007 Workflows - understanding what you can do with the various workflow types available in SharePoint
http://blogs.interknowlogy.com/rodneyguzman/archive/2007/03/20/12405.aspx