WebGrid control header
doesn't support inserting HTML directly. Therefore this implementation uses MvcHtmlString class and simple string
replace to insert a dropdown control to the header. I use a placeholder
called '{StatusFilter}' in the header initially and
then replace that with the HTML markup for the dropdown list.
View:
@model
hub.Models.MyCampModel
@{
if (Model != null && Model.MyCampaigns != null
&& Model.MyCampaigns.Count() > 0)
&& Model.MyCampaigns.Count() > 0)
{
using (Html.BeginForm())
{
var grid = new WebGrid();
grid.Bind(Model.MyCampaigns, rowCount: Model.MyCampaigns.Count());
grid.Pager(WebGridPagerModes.All);
@MvcHtmlString.Create(grid.GetHtml(
tableStyle:
"main_table_wrapper",
alternatingRowStyle:
"descending",
rowStyle:
"ascending",
columns: grid.Columns(
grid.Column("StatusCode", header: "Code"),
grid.Column("Status", header: "Status {StatusFilter}"))
).ToString().Replace("{StatusFilter}", Html.DropDownList("RequestStatusFilter", ViewBag.ReqStatusOptions as SelectList, "All", new { onchange = "$(this).closest('form').submit();" }).ToString()));
}
}
}
Post
action to get filtered results:
[HttpPost]
public ActionResult CampaignList(string requestStatusFilter
= "")
{
MyCampModel model =
new MyCampModel();
model.MyCampaigns =
new List<MyCampaign>();
var myRecs = db.MyCampaigns.Where(itm => (string.IsNullOrEmpty(requestStatusFilter) || itm.MyCampaignStatus.Name == requestStatusFilter));
foreach (var
rec in myRecs)
{
MyCampaign myCamp = new MyCampaign() { StatusCode = rec.Code, Status = rec.MyCampaignStatus.Name };
model.MyCampaigns.Add(myCamp);
}
return
View(model);
ViewBag.ReqStatusOptions
= new SelectList( // logic to select statuses.
}
Here
the drop-down list is rendered in addition to the header text. Therefore
sorting by column headers is also available in the same time.