I have scoured umbraco.tv the farmcode site and blog and for the life of me cannot figure out how to get pagination to work with examine search results. The farmcode post i think is targeted to developers who 'get it' -- unfortunately, i am not a 'real' developer and therefore, don't really 'get it'.
Note, that I've renamed "theCount" to "TotalResults" - we'll get on to that in the code bit next.
Now the code-behind:
using System;
using System.Web.UI.WebControls;
using Examine;
using Examine.LuceneEngine.SearchCriteria;
using System.Linq;
using umbraco;
using umbraco.cms;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.media;
namespace mtt.Search
{
public partial class Examine : System.Web.UI.UserControl
{
public int TotalResults { get; set; }
public string Term { get; set; }
public int PageNumber { get; set; }
public int PageSize { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
//Create search Criteria
var sc = ExamineManager.Instance.CreateSearchCriteria();
//define query
var query = sc.NodeName(Term.MultipleCharacterWildcard())
.Or()
.Field("bodyText", Term.MultipleCharacterWildcard())
.Or()
.Field("FileTextContent", Term.MultipleCharacterWildcard())
.Compile();
var results = ExamineManager.Instance.SearchProviderCollection["FrontSiteSearcher"].Search(Term, true)
.Concat(ExamineManager.Instance.SearchProviderCollection["PDFSearcher"].Search(Term, true));
TotalResults = results.Count();
rp_results.DataSource = results.Skip((PageNumber - 1) * PageSize).Take(PageSize);
rp_results.DataBind();
// pagination
BuildPagination();
}
// helper to build the pagination
private void BuildPagination()
{
decimal d = TotalResults / PageSize;
var pages = Math.Round(d, 0, MidpointRounding.AwayFromZero);
var url = Request.Url.AbsolutePath;
if (PageNumber > 1)
{
var prev = new HyperLink() { NavigateUrl = string.Concat(url, "?q=", Term, "&pageNum=", PageNumber - 1), Text = "Prev" };
phPagination.Controls.Add(prev);
}
for (int i = 1; i <= pages; i++)
{
var page = new HyperLink() { NavigateUrl = string.Concat(url, "?q=", Term, "&pageNum=", i), Text = i.ToString() };
if (PageNumber == i)
page.CssClass = "current";
phPagination.Controls.Add(page);
}
if (PageNumber < pages)
{
var next = new HyperLink() { NavigateUrl = string.Concat(url, "?q=", Term, "&pageNum=", PageNumber + 1), Text = "Next" };
phPagination.Controls.Add(next);
}
}
//simple helper to add summary of search result
public string HighLightSummary(RepeaterItem item)
{
var searchResult = (SearchResult)item.DataItem;
if (searchResult.Fields.ContainsKey("bodyText"))
return umbraco.library.TruncateString(umbraco.library.StripHtml(searchResult.Fields["bodyText"]), 300, "...").Replace(Term, "<strong>" + Term + "</strong>");
if (searchResult.Fields.ContainsKey("FileTextContent"))
return umbraco.library.TruncateString(umbraco.library.StripHtml(searchResult.Fields["FileTextContent"]), 300, "...").Replace(Term, "<strong>" + Term + "</strong>");
return string.Empty;
}
//simple helper to get the name of the node
public string theNodeName(RepeaterItem item)
{
var theName = (SearchResult)item.DataItem;
if (theName.Fields.ContainsKey("bodyText"))
return umbraco.library.NiceUrl(theName.Id);
if (theName.Fields.ContainsKey("umbracoFile"))
return theName.Fields["umbracoFile"].ToString();
return string.Empty;
}
//simple helper to get the extendion of the node
public string theExtension(RepeaterItem item)
{
var theExtension = (SearchResult)item.DataItem;
if (theExtension.Fields.ContainsKey("bodyText"))
return "Conent Node";
if (theExtension.Fields.ContainsKey("umbracoFile"))
return theExtension.Fields["umbracoExtension"].ToString();
return string.Empty;
}
}
}
OK, 2 big changes here. New helper method called "BuildPagination" that creates the pagination links ... and then changing "PageNumber" and "PageSize" into public properties! Why do that? So we can leverage some Macro goodiness! :-D
In your SearchResults/Examine macro, you'll need to add the extra parameters:
Term (text) - think you've already got this in place?
PageNumber (number)
PageSize (number)
Then in your MasterPage template, add those parameters - with the advanced macro syntax, you can pull in values from the querystring ... for the search term and pageNumber (with a fall-back value of "1").
Yeah was thinking the same. Problem is; bob's not a real developer (his own words ;-)) and was already using a Repeater. Removing the repeater and using the listview/datapager instead would be too complex I'm afraid ;-)
it would be awesome to keep this thread going to get a complete 'best practices' solution that one of us could then turn into a wiki article or even a package. As i have said and have been quoted ;) i am NOT a developer so it was much easier to follow Lee's bootstrapped example that added on to what i had, but seeing a complete solution with best practices in mind would be AWESEOME... just sayin :)
Examine and pagination help
I have scoured umbraco.tv the farmcode site and blog and for the life of me cannot figure out how to get pagination to work with examine search results. The farmcode post i think is targeted to developers who 'get it' -- unfortunately, i am not a 'real' developer and therefore, don't really 'get it'.
here is the code i have thus far...
http://pastebin.com/u/bootnumlock
and here is the post on farmcode that i am trying to marry into what i have..
http://www.farmcode.org/post/2010/08/18/Paging-with-Examine.aspx
if anyone could shed some light, that would be awesome... in addition to karma, i could get you a beer at #CG11 :)
Since you're using .NET and the Repeater control (great choice), I'd suggest this post; http://www.4guysfromrolla.com/articles/081804-1.aspx (Adding pagination to a Repeater).
I'll accept the beer :P
so what about the take/skip integration discussed in the farmCode post... i don't need that?
Hi Bob,
Decided to roll my sleeves up and write some example code... here goes:
Firstly add a PlaceHolder control to your ASCX, this will be where the HTML controls for your pagination will be displayed:
Note, that I've renamed "theCount" to "TotalResults" - we'll get on to that in the code bit next.
Now the code-behind:
OK, 2 big changes here. New helper method called "BuildPagination" that creates the pagination links ... and then changing "PageNumber" and "PageSize" into public properties! Why do that? So we can leverage some Macro goodiness! :-D
In your SearchResults/Examine macro, you'll need to add the extra parameters:
Then in your MasterPage template, add those parameters - with the advanced macro syntax, you can pull in values from the querystring ... for the search term and pageNumber (with a fall-back value of "1").
There are probably a few tweaks to the code needed, as I've only given this a small test.
Good luck!
Cheers, Lee.
C'mon Lee, adding controls from code-behind instead of adding them to the template?
Shame on you! ;-)
LOL!
The Prev/Next, sure - could show/hide with Visible property ... but the page numbers? Got a better example? ;-)
LEE! big #H5YR on that one... worked like a dream... thank you so much
Not being much of a developer, i don't really know how to connect everything together... this was very helpul indeed!
you are definitely in for some beers!
@Lee
Prev/next shouldn't be too hard indeed ;-)
I would render the page numbers with a Repeater I guess...
Something like:
Why not just use the ListView webcontrol in combination with the DataPager webcontrol? It works the same as a repeater, but has paging built-in.
Here you can find more info: http://www.codeproject.com/KB/aspnet/ListViewWithDataPager.aspx
Jeroen
@Jeroen
Yeah was thinking the same. Problem is; bob's not a real developer (his own words ;-)) and was already using a Repeater.
Removing the repeater and using the listview/datapager instead would be too complex I'm afraid ;-)
it would be awesome to keep this thread going to get a complete 'best practices' solution that one of us could then turn into a wiki article or even a package. As i have said and have been quoted ;) i am NOT a developer so it was much easier to follow Lee's bootstrapped example that added on to what i had, but seeing a complete solution with best practices in mind would be AWESEOME... just sayin :)
Absolutely, we could cover this at one of the "Hands On" sessions next week! #CG11
BRILLIANT!
Lol, sure Lee ;-)
We can at least discuss this subject :)
Yeah, I'll show you all how to do it in XSLT with uComponents. ;-)
Would be a waste of your and my time though... :P
um, Lee, if that isn't a joke... i would be VERY interested in seeing how that could work!
Haha ... aw come on, XSLT, all that lovely markup, namespaces and tagsoup? What's not to love?
@bob
Shame on you!
@Lee
Shame on you too! :P
@Bob - no joke: http://ucomponents.codeplex.com/wikipage?title=Search
well, crap! i could kick myself!!! so basically you set up the indexes, some simple xslt and BAM!
well, that was days of my life i can never get back :(
is working on a reply...