nev.angelova
nev.angelova

Reputation: 94

MVC Paging- filter view model parameter passed to the action

I'm working on a search functionality with options that are passed with a filter view model:

public class FilterViewModel
{
    public string UserName { get; set; }

    public int? TownId { get; set; }

    [Display(Name = "Gender:")]
    public bool? IsMale { get; set; }

    [Display(Name = "Interests:")]
    public int[] InterestsIds { get; set; }

    public List<ProfileInterest> Interests { get; set; }

    ...

}

The action is called with Ajax:

[HttpPost]
public ActionResult FilterProfiles(FilterViewModel filter)
{
   //Gets the filtered items and returns a partial view     
   ...
}

Is there a paging library to manage Ajax and view model parameter passed to the action.

Upvotes: 0

Views: 1098

Answers (1)

nev.angelova
nev.angelova

Reputation: 94

MvcPaging worked for me. I followed the examples.

In the filter view model I added 'Page' property:

    public class FilterViewModel
    {
        public int? Page { get; set; }

        public string UserName { get; set; }

        public int? TownId { get; set; }

        [Display(Name = "Gender:")]
        public bool? IsMale { get; set; }

        [Display(Name = "Interests:")]
        public int[] InterestsIds { get; set; }

        ...

    }

Then I created a view model to keep the searched result items in IPagedList and the filter options too:

public class CurrentFilterViewModel
{
    //keeps the search result items
    public IPagedList<ProfileViewModel> Profiles { get; set; }

    public string UserName { get; set; }

    public string LastName { get; set; }

    public int? TownId { get; set; }

    public bool? IsMale { get; set; }

    public int[] InterestsIds { get; set; }

    ...

}

In the action I passed the search result items and the filter properties values to the current model properties

    [HttpPost]
    public ActionResult FilterProfiles(FilterViewModel filter)
    {
        var filteredProfilesModel = new CurrentFilterViewModel();
        filteredProfilesModel.UserName = filter.UserName ?? null;
        filteredProfilesModel.TownId = filter.TownId ?? null;
        filteredProfilesModel.IsMale = filter.IsMale ?? null;
        filteredProfilesModel.InterestsIds = filter.InterestsIds ?? new int[0];
        filteredProfilesModel.MusicGenresIds = filter.MusicGenresIds ?? new int[0];

        int DefaultPageSize = 3;
        int currentPageIndex = filter.Page.HasValue ? filter.Page.Value - 1 : 0;

        filteredProfilesModel.Profiles = 
        // ... gets the responded items from the database ...
        .ToPagedList(currentPageIndex, DefaultPageSize);

        return this.PartialView("_FilterProfilesPartial", filteredProfilesModel);
    }

At least, in the partial view which I place with ajax, I put the paging: set the filter parameters values to the current model corresponding properties values. With AddRouteValueFor the collection parameter is set (I use an array to keep the id-s of several selected items).

@using MvcPaging;
@using System.Linq;
@model Project.Web.ViewModels.CurrentFilterViewModel

    <div class="pager">
        @Html.Pager(Model.Profiles.PageSize, Model.Profiles.PageNumber, Model.Profiles.TotalItemCount,
        new AjaxOptions
               {
                   UpdateTargetId = "profiles",
                   HttpMethod = "POST"
               }).Options(o => o
                   .Action("FilterProfiles")
                   .AddRouteValueFor(m => m.InterestsIds)
                   .AddRouteValue("UserName", Model.FirstName)
                   .AddRouteValue("TownId", Model.TownId)
                   .AddRouteValue("IsMale", Model.IsMale)
                   )
    </div>

This solution worked for me. I'm not sure whether it is very elegant. Maybe there is a better one.

Upvotes: 1

Related Questions