I need some help with the select tag helper in ASP.NET Core.
I have a list of employees that I'm trying to bind to a select tag helper. My employees are in a List<Employee> EmployeesList
and selected value will go into EmployeeId
property. My view model looks like this:
public class MyViewModel
{
public int EmployeeId { get; set; }
public string Comments { get; set; }
public List<Employee> EmployeesList {get; set; }
}
My employee class looks like this:
public class Employee
{
public int Id { get; set; }
public string FullName { get; set; }
}
My question is how do I tell my select tag helper to use the Id
as the value while displaying FullName
in the drop down list?
<select asp-for="EmployeeId" asp-items="???" />
I'd appreciate some help with this. Thanks.
Using the Select Tag helpers to render a SELECT element in your view
In your GET action, create an object of your view model, load the
EmployeeList
collection property and send that to the view.And in your create view, create a new
SelectList
object from theEmployeeList
property and pass that as value for theasp-items
property.And your HttpPost action method to accept the submitted form data.
Or
If your view model has a
List<SelectListItem>
as the property for your dropdown items.And in your get action,
And in the view, you can directly use the
Employees
property for theasp-items
.The class
SelectListItem
belongs toMicrosoft.AspNet.Mvc.Rendering
namespace.Make sure you are using an explicit closing tag for the select element. If you use the self closing tag approach, the tag helper will render an empty SELECT element!
The below approach will not work
But this will work.
Getting data from your database table using entity framework
The above examples are using hard coded items for the options. So i thought i will add some sample code to get data using Entity framework as a lot of people use that.
Let's assume your DbContext object has a property called
Employees
, which is of typeDbSet<Employee>
where theEmployee
entity class has anId
andName
property like thisYou can use a linq query to get the employees and use the Select method in your linq expression to create a list of
SelectListItem
objects for each employee.Assuming
context
is your db context object. The view code is same as above.Using SelectList
Some people prefer to use
SelectList
class to hold the items needed to render the options.Now in your GET action, you can use the
SelectList
constructor to populate theEmployees
property of the view model. Make sure you are specifying thedataValueField
anddataTextField
parameters.Here I am calling the
GetEmployees
method to get a list of Employee objects, each with anId
andFirstName
property and I use those properties asDataValueField
andDataTextField
of theSelectList
object we created. You can change the hardcoded list to a code which reads data from a database table.The view code will be same.
Render a SELECT element from a list of strings.
Sometimes you might want to render a select element from a list of strings. In that case, you can use the
SelectList
constructor which only takesIEnumerable<T>
The view code will be same.
Setting selected options
Some times,you might want to set one option as the default option in the SELECT element (For example, in an edit screen, you want to load the previously saved option value). To do that, you may simply set the
EmployeeId
property value to the value of the option you want to be selected.This will select the option Tom in the select element when the page is rendered.
Multi select dropdown
If you want to render a multi select dropdown, you can simply change your view model property which you use for
asp-for
attribute in your view to an array type.This will render the HTML markup for the select element with the
multiple
attribute which will allow the user to select multiple options.Setting selected options in multi select
Similar to single select, set the
EmployeeIds
property value to the an array of values you want.This will select the option Tom and Jerry in the multi select element when the page is rendered.
Using ViewBag to transfer the list of items
If you do not prefer to keep a collection type property to pass the list of options to the view, you can use the dynamic ViewBag to do so.(This is not my personally recommended approach as viewbag is dynamic and your code is prone to uncatched typo errors)
and in the view
Grouping items
The select tag helper method supports grouping options in a dropdown. All you have to do is, specify the
Group
property value of each SelectListItem in your action method.There is no change in the view code. the select tag helper will now render the options inside 2 optgroup items.
In Get:
In Post:
In View :
You can also use IHtmlHelper.GetEnumSelectList.
I created an Interface and a
<options>
tag helper for this. So I didn't have to convert theIEnumerable<T>
items intoIEnumerable<SelectListItem>
every time I have to populate the<select>
control.And I think it works beautifully...
The usage is something like:
And to make it work with the tag helper you have to implement that interface in your class:
These are the needed codes:
The interface:
The
<options>
tag helper:There may be some typo but the aim is clear I think. I had to edit a little bit.
you can use below code for multiple select:
you can also use:
My answer below doesn't solve the question but it relates to.
If someone is using
enum
instead of a class model, like this example:And a property to get the value when submiting:
In the razor page, you can use
Html.GetEnumSelectList<Counter>()
to get the enum properties.It generates the following HTML: