views:

145

answers:

2

Hi there,

I have an MVC view that displays a list of records.

I want to have a check box that allows you to hide / show inactive records.

How can I make it so that when the user checks / unchecks the box, it hits the controller and gets a full or subset list back? Should I use an AJAX call?

Should all this be done on the Index method? (that normally just returns a list of all records).

Any help / ideas appreciated.

A: 

I have been working on a ASP.NET MVC based CRM application for a while. I faced the same issue while fetching a list of leads. What users (i.e., Sales Managers, Sales Representatives, etc) usually like to see in a list of leads is the leads that are "hot" or "active". In my case, I load up all the "hot"/"active" leads in the Index method. I have a partial view (within the Index view) which has a list of checkboxes, these checkboxes represent the various stages of a lead, for example, "contacted", "converted", "closed". When the user clicks on one of the checkboxes, I do an AJAX/jQuery GET of all the leads which have a status in the array of checked checboxes. Example -



   $(document).ready(function() {

      $(".lead-status").click(
         function() {
            var checkedOptions = '';
            $("input[class=lead-status]:checked").each(
               function() {
                  checkedOptions += $(this).attr('name') + ',';
               });

            var leadFilterUrl = "/Lead/FilteredLeadList/?filterString=" + checkedOptions;
            $.get(leadFilterUrl, function(data) {
               var divToShowId = "#leads";
               var divToShow = $(divToShowId);
               divToShow.html('');
               divToShow.html(data);
            },
            "html");

         });
   });    

The partial view of checkboxes is like so -

 <div class="filters-body">
  <div class="checkbox-holder">
     <div id="new-leads-count" style="float:right;"><%= Model.NewLeadsCount.ToString() %></div>
     <%= Html.CheckBox("new", new { @checked = "checked", @class = "lead-status" }) %>
     New
  </div>
  <div class="checkbox-holder">
     <div id="contacted-leads-count" style="float:right;"><%= Model.ContactedLeadsCount.ToString() %></div>
     <%= Html.CheckBox("contacted", new { @checked = "checked", @class = "lead-status" })%>
     Contacted
  </div>   
  <div class="checkbox-holder">
     <div id="following-up-leads-count" style="float:right;"><%= Model.FollowingUpLeadsCount.ToString() %></div>
     <%= Html.CheckBox("following", new { @checked = "checked", @class = "lead-status" })%>
     Following up
  </div>
  <div class="checkbox-holder">
     <div id="rejected-leads-count" style="float:right;"><%= Model.RejectedLeadsCount.ToString() %></div>
     <%= Html.CheckBox("rejected", new { @checked = "checked", @class = "lead-status" })%>
     Rejected
  </div>   
  <div class="checkbox-holder">
     <div id="converted-leads-count" style="float:right;"><%= Model.ConvertedLeadsCount.ToString() %></div>
     <%= Html.CheckBox("converted", new { @checked = "checked", @class = "lead-status" })%>
     Converted
  </div>   
  <div class="summary">
     <div id="total-leads-count" style="float:right;"><b><%= Model.TotalLeadsCount.ToString() %></b></div>
     <b>Total Leads</b>
  </div>

In the FilteredLeadListcontroller, I fetch a list of leads from the database based on the selected filters and return the HTML which is then set in the appropriate div.

I hope this gives an idea of how to use AJAX/jQuery to fetch a partial list of items. I am working on enhancing the application to use JSON instead of HTML which should improve the performance.

Hope this helps, indy

indyfromoz
A: 

Assuming you have controller like this:

public class YourController : Controller {
 public ActionResult ShowOrHide(RecordInfo[] info) {
  RecordInfo[] existing = GetExisting();   
  if (IsPost()) {
   for (int i = 0; i < existing.Length; i++) {
    // Merge so it will go to the View Model in case of validaiton errror
    // Should also check the array bounds
    r.IsVisible = info[i].IsVisible;
    ShowOrHideRecord(r);
   }
   return RedirectToAnotherAction();
  }
  return View(existing);
 }
}

And view like this:

<% for(int i=0; i <= Model.Length; i++) { %>
 <div class="item">
  <% var name = "info[" + i + "].IsVisible"; %>
  <% Html.CheckBox(name) %>
  <label for="<%=name.Replace('.', '_')%>"><%= Model[i].Caption %></label>
 </div>
<% } %>

Everything should work. Just pay attention to the possible NULLs.

This will work with no AJAX at all or you can easily wrap it with AjaxForm the usual way. So graceful degradation will work too.

Dmytrii Nagirniak