Es de todos modos hay que tener un SelectList rellena en ViewModel con datos de atributos ?

Quiero hacer

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

por lo que genera un código como :

<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>
InformationsquelleAutor Bart Calixto | 2013-07-15

5 Comentarios

  1. 95

    Aquí está la solución simple.

    No todo tiene que ser escrito con el método de extensión en .NET de código. Una de las grandes cosas acerca de MVC es que le da fácil acceso para la construcción de su propio código HTML.

    Con MVC4 usted puede obtener el id y el nombre del elemento en el árbol de expresión con los ayudantes de HTML.NameFor y de 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>

    Suponiendo Model.Cities es una colección de elementos que se exponen cada una de esas propiedades. Entonces usted debe estar todo listo.

    Si quieres reutilización, considerar lo que es un editor de plantillas para nada de lo que es Enumerable de las Ciudades

    • Interesante… yo no sé nada de html.namefor etc. Voy a darle una oportunidad
    • Un gran consejo para la adición de real fácil de flexibilidad en el código html.
    • Desde razor2 eliminado usted simplemente puede hacer selected="@city.Value == Model.CityId" y se generará el derecho de marcado (ya sea selected="selected" o nada)
    • ¿Cómo hacer este trabajo sigue con la validación? Mis seleccionar correctamente no resalte en rojo más cuando hay un error en la validación.
    • El código publicado por @Diego no trabajo hasta que he añadido entre paréntesis: selected="@(city.Value == Model.CityId)"
    • que suena bastante bien. Yo no ejecutar el código, simplemente he comentado por el conocimiento de la teoría.
    • es por eso que «No todo tiene que ser escrito con el método de extensión en .NET de código» no es una solución simple. Por suerte en MVC 4 y anteriores, que han proporcionado una manera para obtener la discreta atributos de validación (Html.GetUnobtrusiveValidationAttributes), pero no es bastante. Mira esta respuesta para un revestimiento, o usted podría escribir una ayuda HTML para facilitar la lectura: stackoverflow.com/a/37748259/263832

  2. 11

    Tendrás que extender SelectListItem y, a continuación, extender DropDownListFor el uso de la extendida SelectListItem.

    Echar un vistazo a esta solución:

    La adición de html etiqueta de clase bajo <option> en Html.DropDownList

    • esto se parece a la respuesta correcta, pero parece un poco feo. Yo en lugar de escribir el seleccionar a mí mismo que la ampliación de SelectListItem y DropDownListFor creo. No estoy seguro.
    • No sé por qué piensas que es feo, pero parece más lógico para mí. Cada SelectListItem representa una opción de la etiqueta en el código html final, y lo que necesita hacer es agregar código html personalizado de los atributos para la etiqueta de opción (SelectListItem), por lo que sólo tiene sentido extender el SelectListItem.
    • creo que es feo, desde el marco de mvc perspectiva. pero la solución es exactamente cómo tratar con.
    • De acuerdo, bastante desagradable para añadir algunos atributos simples 🙁
    • Realmente feo solución. Ha sido cubiertos en la última (5.2), la versión de MVC o todavía tirón para escribir código personalizado para que? Gracias
  3. 5

    MVC cuando se convierten los nombres de objeto para nombres de atributo, se relaces «_» con «-«, por lo que su:

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

    NO MI RESPUESTA, RESPUESTA de CRÉDITO se VA A cerca de bruce (sqlwork.com) de la ASP>NET en Foros.

    ¿Cómo puedo agregar data- atributo en dropdownlistfor htmlAttributes?

    SÓLO QUERÍA AYUDAR YA QUE ESTO ME SALVÓ DE LA CODIFICACIÓN DE UN HACK! DISFRUTAR.

    • Esto sólo agrega los datos-rel a la select no a cada option
    • Genial saber que, a pesar de no agregar los atributos como quería (como ParoX mencionado).
  4. 2

    Tuve un requisito similar, he creado una extensión. Espero que sea de ayuda para los que desea crear una extensión.

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

    SelectListItem con datos de atributos

    • Gracias a usted la mejor solución de todas. Me personalizado esta extensión para satisfacer mis necesidades.
  5. 2

    He aquí cómo yo terminé haciendo sin extensión, pero aún permitiendo la validación para continuar el trabajo & estar enlazado a un ViewModel de la propiedad.

    Crea un Html Helper para obtener los atributos de validación como una cadena:

        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() + "\"")));
    }

    Utilizar este helper en un select lista en la vista:

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

    Esto daría como resultado algo como esto:

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

    Voy a dejar el condicional data- atributos de seguridad para usted ya que esos son sólo una cuestión de la formación de la correspondiente máquina de Afeitar expresiones.

Dejar respuesta

Please enter your comment!
Please enter your name here