Click here to Skip to main content
15,892,746 members
Articles / Web Development / ASP.NET
Tip/Trick

MVC HtmlHelper for HTML5 datalist Tag

Rate me:
Please Sign up or sign in to vote.
4.33/5 (2 votes)
8 Sep 2015CPOL 27K   7   2
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:

HTML
<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:

VB.NET
@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:

VB.NET
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:

VB.NET
@Imports MyProject.Mvc.HtmlHelpers

...

@Html.DataListInputFor(Function(m) m.CountryName, Model.GetCountries)

Where Model.GetCountries() could look like:

VB.NET
Public ReadOnly Property GetCountries() As IEnumerable(Of String)
    Get
        Return _db.Countries.Select(Function(c) c.Name)
    End Get
End Property

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionVery nice, but one question Pin
lespauled9-Sep-15 8:27
lespauled9-Sep-15 8:27 
AnswerRe: Very nice, but one question Pin
Adam A Black9-Sep-15 12:06
Adam A Black9-Sep-15 12:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.