Reputation: 344
On my view I have possibility to filter displayed data using Ajax.BeginForm
that returns partail view and refreshes only a table with data. I also have a possibility to sort by column when clicking a column header using Ajax.ActionLink
. The problem is that when I use Ajax.ActionLink
I have to refresh whole page and I loose what was selected in filters (they are custom multiselect combo controls) so whole data is sorted and displayed.
I tried using ViewBag
to send Json data to set back the filters but I failed. I would rather only refresh table even on sort. I am kind of new to MVC.
How to do it in a nice way? Thanks for the help!
View:
@using (Ajax.BeginForm(new AjaxOptions() {HttpMethod = "get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "exposureRecords"}))
{
<div class="form-group">
<select id="brands-select" name="brands" multiple="multiple">
@{
var brands = Model.Brands;
foreach (var item in brands)
{
<option value="@item">@item</option>
}
}
</select>
</div>
(...similar for 3 other filters...)
<table class="table">
<tr>
<th>
@Html.ActionLink("Marka", "Index", new { sortOrder = ViewBag.BrandSortParam })
</th>
<th>
@Html.ActionLink("Dyscyplina", "Index", new { sortOrder = ViewBag.DisciplineSortParm })
</th>
<th>
@Html.ActionLink("Miesiąc", "Index", new { sortOrder = ViewBag.MonthSortParm })
</th>
<th>
@Html.ActionLink("Liczba ekspozycji", "Index", new { sortOrder = ViewBag.QuantitySortParm })
</th>
<th>
@Html.ActionLink("Ekwiwalent reklamowy", "Index", new { sortOrder = ViewBag.ValueSortParm })
</th>
</tr>
</table>
}
@Html.Partial("_Table",Model)
then in controller I have
public ActionResult Index(IEnumerable<string> brands, IEnumerable<string> disciplines,
IEnumerable<string> months,string sortOrder)
{
ViewBag.BrandSortParam = String.IsNullOrEmpty(sortOrder) ? "brand_desc" : "";
ViewBag.DisciplineSortParm = sortOrder == "discipline" ? "discipline_desc" : "discipline";
ViewBag.MonthSortParm = sortOrder == "month" ? "month_desc" : "month";
ViewBag.QuantitySortParm = sortOrder == "quantity" ? "quantity_desc" : "quantity";
ViewBag.ValueSortParm = sortOrder == "value" ? "value_desc" : "value";
model.ExposureRecords = FilterExposure(brands, disciplines, months);
model.ExposureRecords = Sort(sortOrder, model.ExposureRecords);
if (Request.IsAjaxRequest())
return PartialView("_Table", model);
return View(model);
}
Upvotes: 1
Views: 2458
Reputation: 977
My suggestion would be to use a client-side library. Sorting can be done in the controller, but in my experience, it is usually painful. I recently did what you're looking to accomplish in a project using sorttable.js, although there are several options to choose from (see Porschiey's comment above).
To use sortable, add the "sortable" class to your table. Also, be sure to run the "makesortable" js using the OnComplete property in your ajax.beginform ajaxoptions, that way the table will sort after an ajax call. Like this:
@using (Ajax.BeginForm(new AjaxOptions() {HttpMethod = "get", InsertionMode = InsertionMode.Replace, UpdateTargetId = "exposureRecords", OnComplete="makesortable"}))
{
...
}
function makesortable() {
sorttable.makeSortable(document.getElementById('exposureRecords'));
};
Upvotes: 2