Using HTML DataList with ASP.NET Core
By FoxLearn 2/27/2025 7:34:23 AM 25
What is a Datalist?
As the name suggests, the <datalist>
element allows developers to create a list of options for form input fields. This enables users to select from a predefined list curated by the developer while still having the option to input their own custom text.
<label for="ice-cream-choice">Choose a flavor:</label> <input list="ice-cream-flavors" id="ice-cream-choice" name="ice-cream-choice"/> <datalist id="ice-cream-flavors"> <option value="Chocolate"></option> <option value="Coconut"></option> <option value="Mint"></option> <option value="Strawberry"></option> <option value="Vanilla"></option> </datalist>
In this example, the input field is tied to the datalist
element, providing users with a dropdown of available options, while still allowing them to type their own entries.
The list
attribute works with various input types, such as text, date, range, and color. However, it is worth noting that Firefox has partial support, and it doesn't work well with the date
, time
, range
, and color
types.
How to Use Datalist in ASP.NET Core MVC and Razor Pages?
Now, let's implement a solution for using a datalist in Razor Pages.
C# Page Model
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.Rendering; namespace OutputValues.Pages { public class IndexModel : PageModel { [BindProperty] public string? Value { get; set; } public string? Message { get; set; } public List<SelectListItem> Fruits { get; } = new() { new("The finest from Tokyo", "Apple"), new("The curviest fruit", "Banana"), new("The citrus is amazing", "Orange") }; public void OnGet() { } public void OnPost() { Message = $"You selected {Value}!"; } } }
In this code, we define a list of fruits using the SelectListItem
class, which will be used to populate the datalist.
Razor View
<form method="post" asp-page="Index"> <div> <label class="form-label" asp-for="Value"></label> <input class="form-control" asp-for="Value" asp-list="Fruits" /> </div> <button type="submit" class="mt-3 btn btn-primary"> Add </button> <datalist asp-items="Fruits"></datalist> </form>
With this implementation, we now have an input field backed by the datalist.
<form method="post" action="/"> <div> <label class="form-label" for="Value">Value</label> <input class="form-control" type="text" id="Value" name="Value" value="" list="Fruits"> </div> <button type="submit" class="mt-3 btn btn-primary"> Add </button> <datalist id="Fruits"> <option label="The finest from Tokyo" value="Apple"></option> <option label="The curviest fruit" value="Banana"></option> <option label="The citrus is amazing" value="Orange"></option> </datalist> <input name="__RequestVerificationToken" type="hidden" value=""> </form>
The input element is now linked to the datalist through the list
attribute, and the <datalist>
is populated with the list of options derived from the Fruits
property.
Datalist TagHelper Implementation
To make this integration seamless, we’ll create two tag helpers: one for the <datalist>
element and another for the <input>
element.
Datalist Helper Tag
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Razor.TagHelpers; namespace DataList { [HtmlTargetElement("datalist", Attributes = ItemsAttributeName)] public class DataListHelper : TagHelper { private const string ItemsAttributeName = "asp-items"; [HtmlAttributeName(ItemsAttributeName)] public ModelExpression For { get; set; } = default!; public override void Process(TagHelperContext context, TagHelperOutput output) { var items = (IEnumerable<SelectListItem>)For.Model ?? new List<SelectListItem>(); foreach (var item in items) { var tagBuilder = new TagBuilder("option") { Attributes = { ["value"] = item.Value } }; if (!string.IsNullOrWhiteSpace(item.Text)) { tagBuilder.Attributes["label"] = item.Text; } output.PostContent.AppendHtml(tagBuilder); } if (!output.Attributes.ContainsName("id")) { var id = GetDatalistId(For); output.Attributes.SetAttribute("id", id); } } public static string GetDatalistId(ModelExpression forExpression) { return TagBuilder.CreateSanitizedId(forExpression.Name, ""); } } }
Input Helper Tag
using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Razor.TagHelpers; namespace DataList { [HtmlTargetElement("input", Attributes = ItemsAttributeName)] public class DataListInputHelper : TagHelper { private const string ItemsAttributeName = "asp-list"; [HtmlAttributeName(ItemsAttributeName)] public ModelExpression For { get; set; } = default!; public override void Process(TagHelperContext context, TagHelperOutput output) { if (!output.Attributes.ContainsName("list")) { var listId = DataListHelper.GetDatalistId(For); output.Attributes.SetAttribute("list", listId); } } } }
These tag helpers simplify associating the input and datalist elements. The ModelExpression
is key here, allowing us to work with both the metadata and value of the property.
The <datalist>
element is a native HTML feature that enhances several input types with completion suggestions. By using simple tag helpers, we can easily create datalist-backed inputs in ASP.NET Core, keeping the UI and data models in sync with minimal effort.
- Dynamic Menus in ASP.NET Core
- How to Add Swagger in .NET
- What is HSTS
- HTML5 Validation for ASP.NET Core
- Using HTML Range Inputs with ASP.NET Core TagHelpers
- How to Use Conditional Middleware in ASP.NET Core
- How to use the FromServices attribute in ASP.NET Core
- How to use the Developer Exception Page in ASP.NET Core