Thursday, April 14, 2011

Search against a list by using FilterName FilterMultiValue with Pagination

Some blogs talked about using FilterName FilterMultiValue as query string in the url to search on a list (you can google the two names and see what I mean) but there are some issues in this solution. One big problem is pagination. After navigate to the second page, the results are not filtered by the keyword anymore, instead it shows up all records on that page.

I recently worked on this issue and have a workable solution to it. My thought was to rewrite the url after user clicked the page button in the OnPreRender event. This solution basically fires a second redirection with the rewritten url which contains the FilterName FilterMultiValue query strings. You can also put the keyword back in the text box in the OnPreRender event which is a bonus.

It’s a web part created in a sandboxed solution. Here is the sample code:

protected override void CreateChildControls()
{
    //the search keyword box
    var searchBox = new TextBox();
    searchBox.ID = "keyword";
 
    ...
 
    //the literal to hold the javascript
    var literal = new Literal();
    literal.ID = "script";
 
    ...
 
    //search button
    var searchButton = new ImageButton();
 
    ...
}
 
protected override void OnPreRender(EventArgs e)
{
    try
    {
        base.OnPreRender(e);
        
        var keyword = (TextBox)this.FindControl("keyword");
        var script = (Literal)this.FindControl("script");
        if (keyword == null || script == null) return;
 
        //rewrite the url
        var url = HttpContext.Current.Request.Url.AbsoluteUri;
        if (url.IndexOf("FilterName=") <= 0 && url.IndexOf("FilterMultiValue=") <= 0)
        {
            if (!url.EndsWith("aspx") && keyword.Text.Trim() != "")
                script.Text = "<script type='text/javascript'>window.location='" + url + "&FilterName=" + [FieldToSearch] + "&FilterMultiValue=*" + keyword.Text + "*';</script>";
        }
 
        //set the search box text
        if (url.IndexOf("*") > 0)
        {
            var array = url.Split('*');
            if (array.Length >= 1)
                keyword.Text = array[1];
        }
 
    }
    catch { }
}

No comments: