2011-11-20 74 views
0

我是搖滾我自己定製的HtmlHelper啓用AutoComplete support on a Select List自定義htmlhelper驗證支持

這是行得通的,除了我需要能夠支持ViewModel中的DataAnnotations。

這裏是我當前的(工作)的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

回答

5

任何引用您必須下載source code,你會發現DropDownListFor幫手實施在mvc3-rtm-sources.zip\mvc3-rtm-sources\mvc3\src\SystemWebMvc\Mvc\Html\SelectExtensions.cs內。要啓用客戶端驗證,您必須在下拉列表中發佈HTML5數據屬性。這是通過調用htmlHelper.GetUnobtrusiveValidationAttributes方法在SelectInternal方法結束時完成的。

<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 
+0

感謝達林,這將是聰明,能發送模型而不是字符串?類似於你如何做'TextBoxFor'?如果是這樣,那可能是什麼樣子? –

+0

@ChaseFlorell,是的,使用強類型助手'AutoCompleteDropDownListFor'獲取lambda表達式而不是硬編碼魔術字符串將會好得多。我已經更新了我的答案來舉例說明。 –

+0

光榮!謝謝。 –