griegs
griegs

Reputation: 22760

Maintain State when Paging

I have a controller called "Categories" and you are allowed to type a few letters and get a filtered list back.

Fairly standard stuff. However, I'm combining the result set with paging and have run into a snag.

When you first come into the page I have all categories listed. When you type into the text box you get a filtered list but I only return the list and re-display it. I don't show te whole page again.

Now when I hit the page 2 link, the filters are lost and I'm back to my whole list again.

I realise that in the code below I'm not grabbing the filter text in my category ActionResult and this is my problem I think. Just need tp know how to get it there.

How can I maintain the list? Relevant code below;

Controller

    public ActionResult Categories(int? page)
    {
        CategoriesDataRepository categoriesRepository = new CategoriesDataRepository();
        CategoriesFormViewModel fvm = new CategoriesFormViewModel();
        fvm.categories = categoriesRepository.All().OrderBy(x => x.name).ToPagedList(page.HasValue ? page.Value - 1 : 0, CacheHelper.Get().CategoryPageSize);
        return View(fvm);
    }

    public ActionResult jQueryFilterCategories(String filter)
    {
        CategoriesDataRepository categoriesRepository = new CategoriesDataRepository();
        return PartialView("CategoryList", categoriesRepository.All().Where(x => x.name.ToLower().Contains(filter.ToLower())).OrderBy(x => x.name).ToPagedList(0, CacheHelper.Get().CategoryPageSize));
    }

View

<script type="text/javascript">
            $('.FindCategory').keyup(function () {
                var searchText = $('.FindCategory').val();

                $.post('/Home/jQueryFilterCategories', { filter: searchText }, function (newHTML) {
                    $('.Categories').html(newHTML);
                    return false;
                });
            });
</script>

<div class="pager">
    <%= Html.Pager(Helpers.CacheHelper.Get().CategoryPageSize, Model.categories.PageNumber, Model.categories.TotalItemCount, "Categories", "Home")%>
</div>

<div class="CategoryList">
    <div>
        <p>Type here to find categories <%= Html.TextBox("searchTerm", Model.searchTerm, new { @class = "FindCategory" })%></p>
    </div>

    <div class="Categories">
        <% Html.RenderPartial("CategoryList", Model.categories); %> 
    </div>
</div>

Upvotes: 1

Views: 914

Answers (2)

Charmander
Charmander

Reputation: 196

You should try giving your links a function to redisplay through jquery, rather than an href. Then you won't have to reload the page.

$(".link").click(function() {
    //redisplay results
});

Upvotes: 1

kojoru
kojoru

Reputation: 807

public ActionResult Categories(int? page, string? filter)
{
    CategoriesDataRepository categoriesRepository = new CategoriesDataRepository();
    CategoriesFormViewModel fvm = new CategoriesFormViewModel();
    if (filter == null)
         fvm.categories = categoriesRepository.All().OrderBy(x => x.name).ToPagedList(page.HasValue ? page.Value - 1 : 0, CacheHelper.Get().CategoryPageSize);
    else
        fvm.categories = categoriesRepository.All().Where(x => x.name.ToLower().Contains(filter.ToLower())).OrderBy(x => x.name)ToPagedList(page.HasValue ? page.Value - 1 : 0, CacheHelper.Get().CategoryPageSize);
    return View(fvm);
}

Also, you should modify your ActionLinks in your partial CategoryList accordingly.

Upvotes: 4

Related Questions