user101306
user101306

Reputation: 107

mvc jquery paging search results with only 1 query

I have a search page that I'm implementing as part of an ASP.NET + MVC + jquery site. The search query scores each result that is returned as part of the results set. i.e. Higher score for closer match.

Because the results set can change, and because the algorithm that scores the matches is somewhat intensive, I only want to load the results once and to find a way to click through the pages of results.

I figured that I would make a page that contained all of the search results (each result has its own ) and just show/hide a subset by clicking on buttons associated with jquery code. I think I can see how to do this before I start trying to make it work (I'm still fairly new to jquery), but thought I'd first see if anyone has any better ideas.

Thanks in advance for any suggestions.

Edit: Francisco's suggestion was just what I needed. I implemented it with some minor changes and created some jquery buttons to navigate to first/prev/next/last page along with a 'Viewing results n-m out of N' label. Thanks for all the suggestions.

Upvotes: 1

Views: 1720

Answers (3)

Francisco
Francisco

Reputation: 4101

I think your idea is good enough.

Just put all the elements you want from each page into differents divs. Then give the div a class or id attribute that is easily identifiable, such as:

<div id="page1" class="divpage">
page 1 html here
</div>
<div id="page2" class="divpage">
page 2 html here
</div>

etc

The jQuery code would look like this:

$("#page1").show();
$(".divpage").hide(); //this hides all other divs

Edit:

To do this dynamically, creat a strongly-typed view associated to your list of results. The header of the view should be something like:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Result>>" %>

With "result" being your class:

public class Result
{
    int score {get;set;}
    string data {get;set;}
}

Then in your view, you put this:

<%int resultsPerPage = 10;
int currentResults = 0;
int numPage=0;

foreach(var item in Model) 
{   
    if (currentResults==0) Response.Write("<div id=\"page"+numPage+"\" class=\"divpage\">");
    %>

    <%=item.score.ToString()%>
    <%=item.data%>

    <%currentResults++;
    if (currentResults>resultsPerPage)
    {
        numPage++;
        currentResults=0;
        Response.Write("</div>");
    }
}%>

<%if (currentResults!=0) Response.Write("</div>");%>

Then for your buttons:

<%for (int i=0;i<numPage;i++)
{
%>
<a href="" onclick="showPage('<%=i%>');return false;">Page <%=i%></a>

<%}%>

<script type="text/javascript">

function showPage(num)
{
    $("#page"+num).show();
    $(".divpage").hide();
}

</script>

Finally, in your controller:

public ActionResult ShowResults()
{
    List<Result> results = getResultsOrdererdByScoreFunction();
    return View(results);
}

Upvotes: 1

redsquare
redsquare

Reputation: 78667

Cache the results and page through the cached resultset. Maybe using a combination of jqGrid and json.

However you do not really include enough information for us to give the best approach.

You need to do some analysis first.

Factors to consider :

  • How many results is a user likely to look through?

  • Can a user deal with so much information on one page?

  • Is the page going to be slow if you render the whole result set?

UPDATE

Another option could be to use Infinite Scroll. Basically as the user scrolls the results and is towards the end of the screen you auto load in x more results. More here and here

Upvotes: 1

Joseph Ferris
Joseph Ferris

Reputation: 12705

Have you considered using something like Lucene.NET for your indexing? Lucene.NET does a very good job in dealing with offsets for paging. The Document instances that you return from your search could contain the key values for the individual records or you could store enough information to represent the visual aspects for each search result for each item, as well.

When the user pages, you just adjust your offset. Things like query caching and optimization are built-in. I pulled down and compiled a few weeks ago and had a POC to build the index, add and remove items from the index, and return results in just a few minutes by cobbling the samples together. I much prefer using a dedicate index for indexing, leaving the database to work more as a dedicated storage medium - but that is my personal preference.

If you decide to check it out, pull and compile the source from their SVN. The "stable" version is a bit outdated.

Edit:

Here is a brief example on paging with Lucene.NET: Paging using Lucene.net

Upvotes: 1

Related Questions