views:

59

answers:

2

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>
+3  A: 
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.

kojo
Yeah but I'm using a 3rd party paging control that doesn't allow for this. I'd need to mod the plugin which is going to be a pain. but i suspect that will need to be the way.
griegs
if you really don't want to (or can not) modify your paging control, you could try modifying link on client side using jquery.
kojo
@kojo, that's exactly what i ended up doing but that's not to say that your answer wasn't also correct. :) thanks
griegs
+1  A: 

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
});
Charmander
Yeah I really like this. problem is i'm using a 3rd party plugin that i'd need to mod to make this work. not the end of the world just a pain.
griegs
Maybe it's time to switch plugins? Lol, jk.
Charmander
That thought has also crossed my mind. :)
griegs