custom htmlhelper with validation support

我与影子孤独终老i 提交于 2019-11-28 13:01:32
Darin Dimitrov

You will have to download the source code and you will find the implementation of the DropDownListFor helper inside mvc3-rtm-sources.zip\mvc3-rtm-sources\mvc3\src\SystemWebMvc\Mvc\Html\SelectExtensions.cs. To enable client side validation you have to emit HTML5 data-* attributes on the drop down. This is done towards the end of the SelectInternal method by calling htmlHelper.GetUnobtrusiveValidationAttributes method.

<Extension()>
Public Function AutoCompleteDropDownList(ByVal helper As HtmlHelper, name As String, autoCompleteSelectListItem As List(Of AutoCompleteSelectListItem), htmlAttributes As Object) As MvcHtmlString
    Dim selectBuilder As New TagBuilder("select")
    selectBuilder.MergeAttribute("name", name)
    selectBuilder.MergeAttributes(New RouteValueDictionary(htmlAttributes))
    selectBuilder.MergeAttribute("autocorrect", "off")
    selectBuilder.MergeAttribute("autocomplete", "off")

    Dim selectListBuilder As New TagBuilder("option")
    selectListBuilder.MergeAttribute("value", "")
    selectListBuilder.MergeAttribute("selected", "selected")

    Dim innerHtmlBuilder As New StringBuilder
    innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))


    For Each item In autoCompleteSelectListItem
        selectListBuilder = New TagBuilder("option")
        selectListBuilder.MergeAttribute("value", item.Value)
        selectListBuilder.MergeAttribute("data-alternative-spellings", item.AlternativeSpellings)
        selectListBuilder.MergeAttribute("data-relevancy-booster", item.RelevancyBooster)
        selectListBuilder.InnerHtml = item.Label
        innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
    Next

    selectBuilder.InnerHtml = innerHtmlBuilder.ToString()
    selectBuilder.MergeAttributes(helper.GetUnobtrusiveValidationAttributes(name))

    Return MvcHtmlString.Create(selectBuilder.ToString(TagRenderMode.Normal))
End Function

UPDATE:

As requested in the comments section, here's how a strongly typed version of the helper would look like:

<Extension()>
Public Function AutoCompleteDropDownListFor(Of TModel, TProperty)(helper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TProperty)), autoCompleteSelectListItem As List(Of AutoCompleteSelectListItem), htmlAttributes As Object) As IHtmlString
    Dim name = ExpressionHelper.GetExpressionText(expression)
    Dim fullHtmlFieldName As String = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name)

    Dim selectBuilder = New TagBuilder("select")
    selectBuilder.MergeAttribute("name", fullHtmlFieldName)
    selectBuilder.MergeAttributes(New RouteValueDictionary(htmlAttributes))
    selectBuilder.MergeAttribute("autocorrect", "off")
    selectBuilder.MergeAttribute("autocomplete", "off")

    Dim selectListBuilder = New TagBuilder("option")
    selectListBuilder.MergeAttribute("value", "")
    selectListBuilder.MergeAttribute("selected", "selected")

    Dim innerHtmlBuilder = New StringBuilder()
    innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))

    For Each item In autoCompleteSelectListItem
        selectListBuilder = New TagBuilder("option")
        selectListBuilder.MergeAttribute("value", item.Value)
        selectListBuilder.MergeAttribute("data-alternative-spellings", item.AlternativeSpellings)
        selectListBuilder.MergeAttribute("data-relevancy-booster", item.RelevancyBooster)
        selectListBuilder.InnerHtml = item.Label
        innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
    Next

    selectBuilder.InnerHtml = innerHtmlBuilder.ToString()
    selectBuilder.MergeAttributes(helper.GetUnobtrusiveValidationAttributes(name))

    Return MvcHtmlString.Create(selectBuilder.ToString(TagRenderMode.Normal))
End Function
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!