MVC HtmlHelper for HTML5 datalist Tag






4.33/5 (2 votes)
MVC HtmlHelper for HTML5 datalist Tag
Introduction
Recently, I used the datalist tag in my ASP.NET MVC application and I decided to create an MVC HtmlHelper
extension method to achieve this.
This is what the HTML of a datalist
tag looks like:
<input list="browsers">
<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
and with the extension method outlined in this tip, you should be able to generate both tags using the following Razor syntax:
@Html.DataListInputFor(Function(m) m.CountryName, Model.GetCountries)
Using the Code
The HtmlHelper
will generate the input tag and associated datalist
tag. Let's take a look at what the HtmlHelper
looks like:
Option Strict On
Option Explicit On
Imports System.Linq.Expressions
Imports System.Runtime.CompilerServices
Namespace Mvc.HtmlHelpers
''' <summary>
''' Create an input and associated datalist tag. See:
''' http://www.w3schools.com/tags/tag_datalist.asp
''' </summary>
''' <remarks></remarks>
Public Module DataListInputExtensions
<Extension>
Public Function DataListInputFor(Of TModel, TProperty)(
htmlHelper As HtmlHelper(Of TModel),
expression As Expression(Of Func(Of TModel, TProperty)),
dataListItems As IEnumerable(Of String)) As IHtmlString
Return htmlHelper.DataListInputFor(expression, dataListItems, Nothing)
End Function
<Extension>
Public Function DataListInputFor(Of TModel, TProperty)(
htmlHelper As HtmlHelper(Of TModel),
expression As Expression(Of Func(Of TModel, TProperty)),
dataListItems As IEnumerable(Of String),
htmlAttributes As Object) As IHtmlString
Dim html As New StringBuilder
Dim input As New TagBuilder("input")
input.MergeAttributes(htmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes))
' Create the input tag which will reference the datalist.
Dim metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData)
Dim fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(
ExpressionHelper.GetExpressionText(expression))
input.GenerateId(fullName)
input.Attributes("name") = fullName
'Make sure ToString won't cause an exception of the Model is null.
input.Attributes("value") = If(metadata.Model IsNot Nothing,
metadata.Model.ToString,
String.Empty)
' Create the datalist tag which contains the list of searchable items.
Dim dataList As New TagBuilder("datalist")
dataList.GenerateId(String.Format("datalist_{0}", fullName))
input.Attributes("list") = dataList.Attributes("id")
' Populate the datalist with options.
Dim optionsHtml As New StringBuilder
For Each item In dataListItems
Dim opt As New TagBuilder("option")
opt.Attributes("value") = item
optionsHtml.AppendLine(opt.ToString)
Next
dataList.InnerHtml = optionsHtml.ToString
html.AppendLine(input.ToString)
html.AppendLine(dataList.ToString)
Return New HtmlString(html.ToString)
End Function
End Module
End Namespace
The HtmlHelper
can then be used as follows:
@Imports MyProject.Mvc.HtmlHelpers
...
@Html.DataListInputFor(Function(m) m.CountryName, Model.GetCountries)
Where Model.GetCountries()
could look like:
Public ReadOnly Property GetCountries() As IEnumerable(Of String)
Get
Return _db.Countries.Select(Function(c) c.Name)
End Get
End Property