Html 带有数据属性的 SelectListItem

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17665426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 11:11:22  来源:igfitidea点击:

SelectListItem with data-attributes

asp.net-mvchtmlhtml-helpercustom-data-attributeselectlist

提问by Bart Calixto

Is there anyway to have a SelectList prepopulated on ViewModel with data-attributes ?

有没有在 ViewModel 上预先填充数据属性的 SelectList ?

I want to do

我想要做

@Html.DropdownListFor(m=> m.CityId, Model.Cities);

so it generates code like :

所以它生成的代码如下:

<select id="City" class="location_city_input" name="City">
    <option data-geo-lat="-32.522779" data-geo-lng="-55.765835" data-geo-zoom="6" />
    <option data-geo-lat="-34.883611" data-geo-lng="-56.181944" data-geo-zoom="13" data-geo-name="Montevideo" data-child=".state1" value="1">Montevideo</option>               
    <option data-geo-lat="-34.816667" data-geo-lng="-55.95" data-geo-zoom="13" data-geo-name="Canelones, Ciudad de la Costa" data-child=".state41" value="41">Ciudad de la Costa</option>
</select>

回答by KyleMit

Here's the simple solution.

这是简单的解决方案。

Not everything has to be written with extension method in .NET code. One of the great things about MVC is it gives you easy access to construct your own HTML.

并非所有内容都必须在 .NET 代码中使用扩展方法编写。MVC 的一大优点是它使您可以轻松访问构建自己的 HTML。

With MVC4 you can get the id and name of the element on the expression tree with the helpers HTML.NameForand HTML.IdFor

随着MVC4你可以得到元素的ID和名称上与助手表达式树HTML.NameForHTML.IdFor

<select name="@Html.NameFor(Function(model) model.CityId)"
        id="@Html.IdFor(Function(model) model.CityId)"
        class="location_city_input">
    @For Each city In Model.Cities
        @<option value="@city.Value"
                 @(If(city.Value = Model.CityId, "selected", ""))
                 data-geo-lat="@city.Lat"
                 data-geo-lng="@city.Lng"
                 data-geo-zoom="@city.Zoom">
            @city.Text
        </option>
    Next
</select>

Assuming Model.Citiesis a collection of items that expose each of those properties. Then you should be all set.

假设Model.Cities是公开每个属性的项目集合。那么你应该一切都准备好了。

If you want reusability, consider making it an editor template for anything that is an Enumerable of Cities

如果您想要可重用性,请考虑将其设为可枚举城市的任何编辑器模板

回答by ataravati

You'll have to extend SelectListItem, and then extend DropDownListFor to use the extended SelectListItem.

您必须扩展 SelectListItem,然后扩展 DropDownListFor 以使用扩展的 SelectListItem。

Have a look at this solution:

看看这个解决方案:

Adding html class tag under <option> in Html.DropDownList

在 Html.DropDownList 中的 <option> 下添加 html class 标签

回答by xr280xr

Here's how I ended up doing it without an extension but still enabling unobtrusive validation to continue to work & be bound to a ViewModel property.

这是我最终在没有扩展的情况下完成它但仍然启用不显眼的验证以继续工作并绑定到 ViewModel 属性的方式。

Created an Html Helper to get the validation attributes as a string:

创建了一个 Html Helper 以获取字符串形式的验证属性:

    public static IHtmlString GetUnobtrusiveValidationAttributesFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> propertySelector)
    {
        string propertyName = html.NameFor(propertySelector).ToString();
        ModelMetadata metaData = ModelMetadata.FromLambdaExpression(propertySelector, html.ViewData);
        IDictionary<string, object> attributeCollection = html.GetUnobtrusiveValidationAttributes(propertyName, metaData);

        return html.Raw(String.Join(" ", attributeCollection.Select(kvp => kvp.Key + "=\"" + kvp.Value.ToString() + "\"")));
    }

Use this helper in a selectlist in the view:

select在视图的列表中使用此助手:

<select name="@Html.NameFor(m => m.CityId)" id="@Html.IdFor(m => m.CityId)"
    @Html.GetUnobtrusiveValidationAttributesFor(m => m.CityId)
    class="location_city_input">
    @foreach(var city in Model.Cities)
    {
        <option value="@city.Id.ToString()" @(city.Id == Model.CityId ? "selected" : "") 
            data-geo-lat="@city.Lat" data-geo-lng="@city.Lng" data-geo-zoom="@city.Zoom">
            @city.Name
        </option>
    }
</select>

This would output something like this:

这将输出如下内容:

<select id="CityId" name="CityId" 
    data-val-required="The SelectedTaxRateID field is required." data-val="true" 
    class="location_city_input">
    <option value="1" selected data-geo-lat="-34.883611" data-geo-lng="-56.181944" data-geo-zoom="13">Montevideo</option>               
    <option value="41" data-geo-lat="-34.816667" data-geo-lng="-55.95" data-geo-zoom="13">Ciudad de la Costa</option>
</select>

I will leave the conditional data-attributes up to you since those are just a matter of forming the appropriate Razor expressions.

我将把条件data-属性留给你,因为这些只是形成适当的 Razor 表达式的问题。

回答by Takumi

MVC when it converts object names to attribute names, it relaces "_" with "-", so its:

MVC 将对象名称转换为属性名称时,会将“_”替换为“-”,因此其:

@Html.DropDownList(a=>a.websiteid, Model.GetItems, new{ data_rel="selected" })

NOT MY ANSWER, ANSWER CREDIT GOES TO About bruce (sqlwork.com) from the ASP>NET Forums.

不是我的答案,答案来自 ASP>NET 论坛中的 About bruce (sqlwork.com)。

How can I add data-rel="selected" attribute into dropdownlistfor htmlAttributes?

如何将 data-rel="selected" 属性添加到 htmlAttributes 的下拉列表中?

JUST WANTED TO HELP OUT AS THIS SAVED ME FROM CODING A HACK! ENJOY.

只是想提供帮助,因为这使我免于编写黑客代码!请享用。

回答by aldo

I had a similar requirement, I created a extension. Hope it helps for the ones who wants to create an extension.

我有一个类似的要求,我创建了一个扩展。希望它对想要创建扩展的人有所帮助。

/*cs file*/
/*This contains your information with List<vmListItem>*/
public class vmListItem
{
   public int Id { get; set; }
   public string Name { get; set; }
   public string Tag { get; set; }
}

/*This contains the attributes in select, using List<vmAttribute>. Check cshtml */
public class vmAttribute
{
   public string Key { get; set; }
   public string Value { get; set; }
}

    /// <summary>
    /// Creates a dropdownlist using a list with data attributes included
    /// </summary>
    /// <param name="helper"></param>
    /// <param name="id">id and name of the select</param>
    /// <param name="attributes">list of attrs for select</param>
    /// <param name="items"><list of options/param>
    /// <param name="idSelected">id selected in option</param>
    /// <param name="tagName">data-tagName you can choose the name of your tag</param>
    /// <param name="textHeader">first option in select</param>
    /// <returns></returns>
    public static MvcHtmlString DropDownListForWithTag(this HtmlHelper helper, string id, List<vmAttribute> attributes, List<vmListItem> items, int idSelected, string tagName = "tag", string textHeader= "")
    {
        var select = new TagBuilder("select");
        select.GenerateId(id);
        select.MergeAttribute("name", id);
        foreach (vmAttribute att in atributos) select.MergeAttribute(att.Key, att.Value);

        TagBuilder headerOption = new TagBuilder("option");
        headerOption .MergeAttribute("value", null);
        headerOption .InnerHtml = textHeader;
        select.InnerHtml += headerOption ;

        foreach(var item in items)
        {                
            TagBuilder option = new TagBuilder("option");
            option.MergeAttribute("value", item.Id.ToString());
            option.MergeAttribute("data-" + tagName, item.Tag);
            if (idSelected == item.Id) option.MergeAttribute("selected", "selected");
            option.InnerHtml = item.Name;

            select.InnerHtml += option.ToString();
        }

        return new MvcHtmlString(select.ToString());
    }

/*cshtml file*/
@Html.DropDownListForWithTag("MovimientoBienMotivoId", new List<vmAttribute> {
                        new vmAttribute("class", "form-control"),
                        new vmAttribute("data-val", "true"),
                        new vmAttribute("data-val-required", "El campo Motivo es obligatorio"),
                        new vmAttribute("onchange", "movValidarCambioMotivo()"),
                    }, (List<vmListItem>)ViewBag.MovimientoBienMotivoId, Model.MovimientoBienMotivoId, "codigo", "Seleccione")
                    @Html.ValidationMessageFor(model => model.ColumnId, "", new { @class = "text-danger" })


/*html results*/

enter image description here

在此处输入图片说明