How to get a drop down list of imported values, and use it to filter a foreach list of values below it

How to get a drop down list of imported values, and use it to filter a foreach list of values below it

I have a page that lists a bunch of doctors with their specialties, and a drop down list of specialties above it. When you initially open the page, it shows all doctors below the drop down list. I am trying to get it to the point where you pick a specialty from the drop down list, and hit a filter button, it filters out the list of doctors below to show only the doctors with the specialty you selected. I am having a little bit of trouble making it happen.

Here is the controller method that leads into the page:

 [HttpGet]
 public async Task<IActionResult> Index(string specialty)
 {
     List<Doctor> doctors;

     List<string> specialties = await doctorRepository.GetSpecialties();

     if (!string.IsNullOrWhiteSpace(specialty))
     {
         doctors = await context.Doctors
             .Include(d => d.User)
             .Where(d => d.Specialty == specialty)
             .ToListAsync();
     }
     else
     {
         doctors = await context.Doctors
             .Include(d => d.User)
             .ToListAsync();
     }

     var doctorViewModel = new DoctorIndexViewModel
     {
         Doctors = doctors,

         SpecialtyListItems = specialties
             .Distinct()
             .OrderBy(s => s)
             .Select(s => new SelectListItem { Text = s, Value = s })
             .ToList()
     };

     return View(doctorViewModel);
 }

here is the page where I have the list of doctors, with their specialties, and the drop down list:

@model planMyMDVisit.Models.ViewModels.DoctorIndexViewModel

<h2>In-Network Doctors</h2>
<h6>Filter doctors by specialty:</h6>

@*uses a dropdown list of specialties to filter out certain doctors from the list below
<select onclick="" asp-for="SelectedSpecialty" asp-items="Model.SpecialtyListItems" 
id="list" class="form-control">
    <option selected disabled>-- SELECT SPECIALTY--</option>
</select>


@*List of doctors*@
@foreach(var hct in Model.Doctors.GroupBy(d => d.Specialty).OrderBy(d => d.Key))
{
    <h4>@hct.Key</h4>

    @foreach (var doctor in hct.OrderBy(d => d.Name))
    {
        <div>
            <i>@doctor.Specialty</i>
            <strong>
                <a href="@Url.Action("Show", "Doctors", new { id = doctor.Id 
})">@doctor.Name</a>
            </strong>
        </div>
    }
 }

 <script>
     function filterList() {
        
     }
 </script>

I am having trouble trying to get this to work properly. What can I try next?

Answer

  1. You should define the <form> to send the form value to the GET API either with:
<form asp-controller="Doctor" asp-action="Index" method="GET">
  <select asp-for="SelectedSpecialty" asp-items="Model.SpecialtyListItems" 
    id="list" class="form-control" name="specialty">
    <option selected disabled>-- SELECT SPECIALTY--</option>
</select>

  <input id="btnSearch" type="submit" value="Search" />
</form>

Or:

<form method="GET">
  <select asp-for="SelectedSpecialty" asp-items="Model.SpecialtyListItems" 
    id="list" class="form-control" name="specialty">
    <option selected disabled>-- SELECT SPECIALTY--</option>
</select>

  <input id="btnSearch" type="submit" value="Search" />
</form>

By setting the name="specialty" attribute to the <select> element, when the form is submitted, the property value is sent as query parameter.

  1. In your controller action, you should set the passed specialty to the Specialty property so that it will bind the selected value in the <select> element.
[HttpGet]
public async Task<IActionResult> Index(string specialty)
{
   ...

   var doctorViewModel = new DoctorIndexViewModel
   {
       SelectedSpecialty = specialty,
       Doctors = doctors,

       SpecialtyListItems = specialties
           .Distinct()
           .OrderBy(s => s)
           .Select(s => new SelectListItem { Text = s, Value = s })
           .ToList()
     };

     return View(doctorViewModel);
}

Aside, you can combine the query for doctors list by filtering the specialty keyword into one with:

doctors = await context.Doctors
    .Include(d => d.User)
    .Where(d => string.IsNullOrWhiteSpace(specialty) || d.Specialty == specialty)
    .ToListAsync();

Enjoyed this question?

Check out more content on our blog or follow us on social media.

Browse more questions