Reputation: 5480
I have a List of Listings within my Database. On my View, I have a DropDownList which contains categories. A category contains many listings.
When I select a specific category, I wish to only display those listings which have the category selected.
My main worry is how to generate the JQuery to call my SortListing method in my ListingController.
Here is the current HTML (Razor):
@Html.DropDownListFor(m => m.Categories, Model.Categories, "Select a Category")
My SortListing Method:
public List<Listing> SortListing(string categoryId)
{
var listings = new List<Listing>();
foreach (var listing in _service.ListAllEntities<Listing>())
{
if (listing.CategoryId == categoryId)
{
listings.Add(listing);
}
}
return listings;
}
EDIT I have the following. Put the categoryGuid is coming in null.
This is my code:
$(function () {
$('#SelectedCategoryGuid').change(function () {
var url = $(this).data('url');
var categoryId = $(this).val();
$.ajax({
url: url,
type: 'GET',
cache: false,
data: { categoryId: categoryId },
success: function (result) {
// TODO: manipulate the result returned from the controller action
}
});
});
});
</script>
<h2>Index</h2>
@Html.ActionLink("Create New Listing", "Create")
<br/>
<strong>Filter Listings</strong>
@Html.DropDownListFor(
m => m.SelectedCategoryGuid,
Model.Categories,
"Select a Category",
new {
id = "SelectedCategoryGuid",
data_url = Url.Action("SortListing", "Listing")
}
)
Upvotes: 0
Views: 2222
Reputation: 1038780
My main worry is how to generate the JQuery to call my SortListing method in my ListingController.
Actually you should be having other worries as well that I will try to cover throughout my answer.
There's an issue with your DropDownListFor
helper. You have used the same property on your model for both binding the selected category value and the list of categories which is wrong. The first parameter of the DropDownListFor helper represents a lambda expression pointing to a primitive type property on your view model:
@Html.DropDownListFor(
m => m.CategoryId,
Model.Categories,
"Select a Category",
new {
id = "categoryDdl",
data_url = Url.Action("SortListing", "Listing")
}
)
and then subscribe to the .change()
event and trigger the AJAX request:
$(function() {
$('#categoryDdl').change(function() {
var url = $(this).data('url');
var categoryId = $(this).val();
$.ajax({
url: url,
type: 'GET',
cache: false,
data: { categoryId: categoryId },
success: function(result) {
// TODO: manipulate the result returned from the controller action
}
});
});
});
Now let's take a look at your SortListing
controller action because there are issues with it. In ASP.NET MVC standard convention dictates that controller actions must return ActionResults. In your case you seem to be returning some List<Listing>
. So the first thing you have to decide is the format you would like to use. One possibility is to return those listings as JSON formatted values:
public ActionResult SortListing(string categoryId)
{
var listings = _service
.ListAllEntities<Listing>()
.Where(x => x.CategoryId == categoryId)
.ToList();
return Json(listings, JsonRequestBehavior.AllowGet);
}
In this case inside your AJAX success callback you will receive this collection of listings and you will have to update your DOM:
success: function(result) {
// result represents an array of listings
// so you could loop through them and generate some DOM elements
}
Another possibility is to have your controller action return a partial view:
public ActionResult SortListing(string categoryId)
{
var listings = _service
.ListAllEntities<Listing>()
.Where(x => x.CategoryId == categoryId)
.ToList();
return PartialView("Listings", listings);
}
and then you will have a corresponding partial view:
@model List<Listing>
@foreach (var listing in Model)
{
<div>@listing.SomeProperty</div>
}
and then inside the success callback you will refresh some containing placeholder:
success: function(result) {
$('#SomeDivIdThatWrapsAroundTheListingsPartial').html(result);
}
So to recap you could either have the controller action return JSON and then manually build the corresponding DOM tree using javascript or return a partial view which will already contain the corresponding markup and simply refresh some containing div with this partial.
Upvotes: 3