83 votes

SelectListItem avec attributs de données

Existe-t-il un moyen d'avoir une SelectList pré-remplie sur le ViewModel avec des data-attributes ?

Je veux faire

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

Il génère donc un code comme :

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

118voto

KyleMit Points 6937

La solution est simple.

Tout ne doit pas nécessairement être écrit avec une méthode d'extension dans le code .NET. L'un des grands avantages de MVC est qu'il vous permet de construire facilement votre propre code HTML.

Avec MVC4, vous pouvez obtenir l'identifiant et le nom de l'élément dans l'arbre d'expression avec les aides HTML.NameFor y HTML.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>

Assumer Model.Cities est une collection d'éléments qui exposent chacune de ces propriétés. Vous devriez alors être prêt.

Si vous voulez pouvoir réutiliser les données, envisagez d'en faire un modèle d'éditeur pour tout ce qui est une énumération de villes.

13voto

ataravati Points 6489

Vous devrez étendre SelectListItem, puis étendre DropDownListFor pour utiliser SelectListItem étendu.

Jetez un coup d'œil à cette solution :

Ajout d'une balise html class sous <option> dans Html.DropDownList

6voto

Takumi Points 85

MVC, lorsqu'il convertit les noms d'objets en noms d'attributs, remplace "_" par "-", donc son :

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

Comment ajouter l'attribut data-rel="selected" dans la liste déroulante de htmlAttributes ?

JUST WANTE

2voto

aldo Points 48

J'ai eu un besoin similaire, j'ai créé une extension. J'espère que cela aidera ceux qui veulent créer une 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X