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
- 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.
- In your controller action, you should set the passed
specialty
to theSpecialty
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