BSB BSB - 2 months ago 9
ASP.NET (C#) Question

How to use more than one partial view to filter data displayed on view

I have a partial view which is used to filter what needs to be displayed on a View.
Below is the code I have written.

Partial View for Location

@using JobSite.Entities
@model IEnumerable<string>

@Html.ActionLink("All jobs", "List", "Job", null, new { @class = "btn btn-
block btn-default btn-lg" })
@foreach(var link in Model)
{
@Html.RouteLink(link, new
{
controller="Job",
action="List",
location=link},
new
{
@class = "btn btn-block btn-default btn-lg"
+ (link==ViewBag.SelectedLocation?"btn-primary":"")
})
}


Partial View for Company

@using JobSite.Entities
@model IEnumerable<string>

@Html.ActionLink("All jobs", "List", "Job", null, new { @class = "btn btn-
block btn-default btn-lg" })
@foreach(var link in Model)
{
@Html.RouteLink(link, new
{
controller="Job",
action="List",
company=link},
new
{
@class = "btn btn-block btn-default btn-lg"
+ (link==ViewBag.SelectedCompany?"btn-primary":"")
})
}


In the controller,I am filtering it based on location.

public ViewResult List(string location)
{
JobListViewModel model = new JobListViewModel();
if (location == null)
{
model = new JobListViewModel
{
jobDetails = repository.jobDetailsInterface
};
}
else
{
model = new JobListViewModel
{
jobDetails = repository.jobDetailsInterface.Where(p => p.JobLocation.LocationName == location)
};
}
return View(model);
}


How can i display the items in the view based upon the selection in both the partial views? I want to develop something like a filtering criteria in Shopping websites.

Sample filter used in shopping websites

Answer Source

I don't think one partial view per search facet is the right way to go (where a facet is something like a location or a company). I think the right way to go is to introduce one level of abstraction on top of your search facets that can hold the metadata about each facet inside of a data structure, instead of that metadata being held as literal and distinct server-side code.

To accomplish this you would need to generalize everything about each of your search facets so that it can be represented as data.

For example, your models might look like this:

public sealed class SearchFacetLinkViewModel {
   public string Name { get; set; }
   public string Link { get; set; }
}

public sealed class SearchFacetViewModel {
   public string Description { get; set; }
   public IEnumerable<SearchFacetViewModel> Links { get; set; }
   public string SelectedFacet { get; set; }
}

Then in your view:

@model IEnumerable<SearchFacetViewModel>

@foreach (var searchFacet in Model) {
   // Insert your above code for your views, but instead,
   // use values from the model instead of hard-coding them
   // so each facet can be generated from within the loop.
   @foreach (var facetLink in searchFacet.Links) {
      // use facetLink.Name and facetLink.Link
   }
}

You can use the session to store up the currently selected facets the user has specified, or you could embed all the current facet state into all the links (so for example, if a location is selected, then each company url emitted also has &location= within it as well). You can also maintain the user's selection state in a database.

In your controller you would either accept all facet values on each submission, or if you are maintaining facet state server-side, you would provide just the "delta" action, such as "remove facet location" or "add facet company=xyz". You may even want to switch to an asychronus/AJAX model where the page doesn't get reloaded and instead of returning whole views, your initial page is more of an empty container, and then AJAX calls to fetch search results using the current facets receive JSON payloads of the matching values (this actually makes maintaining the facets wholly client-side somewhat easier, by removing all need to maintain current facet state server-side). There is also room for, short of AJAX, nonetheless manipulating the URL requested to include all current facet values (not allowing a link's default action to occur but running JavaScript instead).

Please understand that faceted search is a fairly complex topic with many nuances. It's hard to lead you to a comprehensive and best solution, especially because your project has to incrementally develop and improve over time as your knowledge and ability improve. There's no real substitute for the pain of encountering problems caused by your coding choices and then learning how to overcome those (so you choose better next time).