пользовательский htmlhelper с поддержкой валидации - PullRequest
1 голос
/ 21 ноября 2011

У меня есть собственный HtmlHelper для включения поддержки Автозаполнения в списке выбора .

Это работает нормально, за исключением того, что я должен иметь возможность поддерживать аннотации данных в моей модели представления.

Вот мой текущий (рабочий) HtmlHelper (без проверки)

    <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()

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

Как можно переписать это для поддержки валидации? Что-то вроде AutoCompleteDropDownListFor()

PS: решение C # вполне приемлемо, проект, над которым я работаю, находится на VB, но я не против перевода.


PS: я перелистываю исходный код на http://aspnet.codeplex.com и не могу найти ссылку на DropDownListFor

1 Ответ

6 голосов
/ 21 ноября 2011

Вам нужно будет загрузить исходный код , и вы найдете реализацию помощника DropDownListFor внутри mvc3-rtm-sources.zip\mvc3-rtm-sources\mvc3\src\SystemWebMvc\Mvc\Html\SelectExtensions.cs. Чтобы включить проверку на стороне клиента, вы должны указать атрибуты data5 * HTML5 в раскрывающемся списке. Это делается в конце метода SelectInternal путем вызова метода htmlHelper.GetUnobtrusiveValidationAttributes.

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

Как и просили в разделе комментариев, вот как будет выглядеть строго типизированная версия помощника:

<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
...