Use a dropdownlist to filter results in MVC

Matt Ellenburg picture Matt Ellenburg · Aug 8, 2012 · Viewed 12.8k times · Source

I have an MVC web application that returns a table. I want to add a dropdownlist to the view page that filters the table to the selected year. What's the correct approach?

I'm currently creating a dropdownlist that I'm populating using JQuery. I created an onChange command to postback, but I don't know how to get the selected value of the dropdownlist in the controller.

Here are the code pieces I have in place:

In the controller:

    public ActionResult Index()
    {
        int year = 2012;
        var vu_Estimates = dbBudget.vu_Estimates.OrderByDescending(o => o.Expense).ThenBy(o => o.CategoryGroupSortOrder).ThenBy(o => o.SortOrder).Where(o => o.Year == year).ToList();

        return View(vu_Estimates);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Index(FormCollection formCollection)
    {
        int year = 2012;
        var vu_Estimates = dbBudget.vu_Estimates.OrderByDescending(o => o.Expense).ThenBy(o => o.CategoryGroupSortOrder).ThenBy(o => o.SortOrder).Where(o => o.Year == year).ToList();

        return View(vu_Estimates);
    }

In the view, I have the following:

<script type="text/javascript">
    $(document).ready(function () {        
        $.post("/Estimate/PopulateYears/", { Year: $(this).val() }, function (data) {
            populateDropdown($("#ddlYears"), data);
        });
    });

    function populateDropdown(select, data) {
        select.html('');
        $.each(data, function (id, option) {
            select.append($('<option></option>').val(option.value).html(option.name));
        });
    }
</script>

<h2>Estimates List</h2>

<div>
    <% using (Html.BeginForm()) { %>
        <select id="ddlYears" onchange="this.form.submit();"></select> | <%: Html.ActionLink("Create New Year of Estimates", "CreateEstimates", "Estimate") %>
    <%} %>
</div>


<table>
    <tr>
        <th></th>
        <th>
            EstimateID
        </th>
        <th>
            CategoryID
        </th>
        <th>
            Year
        </th>
        <th>
            EstimateAmount
        </th>
        <th>
            CategoryName
        </th>
        <th>
            SortOrder
        </th>
        <th>
            CategoryGroupSortOrder
        </th>
        <th>
            Expense
        </th>
    </tr>

<% foreach (var item in Model) { %>
    <tr>
        <td>
            <%: Html.ActionLink("Edit", "Edit", new { id=item.EstimateID }) %> |
            <%: Html.ActionLink("Delete", "Delete", new { id=item.EstimateID })%>
        </td>
        <td>
            <%: item.EstimateID %>
        </td>
        <td>
            <%: item.CategoryID %>
        </td>
        <td>
            <%: item.Year %>
        </td>
        <td>
            <%: item.EstimateAmount %>
        </td>
        <td>
            <%: item.CategoryName %>
        </td>
        <td>
            <%: item.SortOrder %>
        </td>
        <td>
            <%: item.CategoryGroupSortOrder %>
        </td>
        <td>
            <%: item.Expense %>
        </td>
    </tr>
<% } %>

</table>

<p>
    <%: Html.ActionLink("Create New", "Create") %>
</p>

Answer

emre nevayeshirazi picture emre nevayeshirazi · Aug 9, 2012

I would suggest using AJAX to post the value of dropdownlist and return the data required to update your page using this request. Otherwise, you need to reload your page everytime the value in select element changes.

$('#idOfSelectElement').change( function() {
    $.ajax({
        type: "POST",
        url: '/Estimate/PopulateYears',
        data: { 
            valueOfDropDown: $(this).val()
        },
        /* Response is the data returned from controller method */
        success: function (response) {

           var value1 = response.value1;
           var value2 = response value2;

           //TODO : Use these values to update your page.

           return false;
        }
    });
});

In your controller,

/* Assuming the value of your dropdownlist is integer. If not use string */
public ActionResult PopulateYears(int valueOfDropDown)
{
    try
    {
      /* Get data using the value of dropdownlist */
      var vu_Estimates = getData(valueOfDropDown);

      return Json(new 
      { 
          success = true,
          value1 = vu_Estimates.value1,
          value2 = vu_Estimates.value1
      }, JsonRequestBehavior.AllowGet);
    }
    catch
    {
        return Json(new { success = false } );
    }
}