MVC3 SelectListItem. Можно ли украсить его пользовательскими атрибутами html?

если у меня есть что-то вроде этого:

@{
   var cats = GetCategories();
   var selectList = from c in cats
   select new SelectListItem
   {
     Selected = (c.Id == Model.SessionCategory.Id),
     Text = c.Name,
     Value = c.Id.ToString(),
    };
  }
 @Html.DropDownList("categories", selectList)

Разметка будет такой:

 <select id="categories" name="categories">
    <option value="1">Category1</option>
    <option value="2">Category2</option>
    <option selected="selected" value="3">Category3</option>
 </select>

А теперь вопрос:

Можно ли добавить дополнительные атрибуты к каждому тегу <option>? Я имею в виду из шаблона Razor. Без обходных путей jQuery?


person iLemming    schedule 05.04.2011    source источник
comment
вы пытаетесь добавить дополнительные атрибуты к тегу option или тегу select?   -  person Justin Soliz    schedule 05.04.2011
comment
Извините, я пропустил это. Я должен был поместить это в одинарные кавычки.   -  person iLemming    schedule 05.04.2011


Ответы (3)


Я думаю, что наиболее практичным решением будет какой-нибудь jQuery или, может быть, что-то вроде этого.

<select id="categories" name="categories">
    @foreach (var item in selectList) {
        <option @if (item.Selected) { <text>selected="selected"</text>} value="@item.Value">@item.Text</option>
    }
</select>

вы, очевидно, могли бы добавить атрибуты по мере необходимости...

person Justin Soliz    schedule 05.04.2011
comment
Хех, я собирался сделать это, но я предпочитаю методы @Html :) +1 для вас - person Buildstarted; 05.04.2011

По умолчанию нет. SelectListItem не содержит никаких дополнительных свойств для добавления ваших атрибутов. Однако вы можете создать свой собственный метод DropDownList или DropDownListFor и создать свой собственный ListItemToOption с пользовательским SelectListItem для добавления собственных атрибутов.

Но наверное это перебор.

person Buildstarted    schedule 05.04.2011
comment
Да, это вообще звучит как перебор. Я болею за jQuery, если нет другого простого способа сделать это - person iLemming; 05.04.2011
comment
Я хотел посмотреть, было ли это хотя бы просто... и начал это делать, но было бы так много копий/вставок и модификаций кода, чтобы получить всю функциональность, которую вы ожидаете от HtmlHelpers... И... .Это, вероятно, приведет к ошибкам с расширениями с тем же именем, поэтому вам придется переименовать их все... настоящая боль :) - person Buildstarted; 05.04.2011
comment
Было бы неплохо увидеть пример того, как сделать свою собственную настройку SelectListItem. - person Serj Sagan; 05.11.2013
comment
Вот пример того, как вы можете расширить SelectListItem и иметь свой собственный метод расширения DropDownlistFor stackoverflow.com/a/7537628/1689049 - person Alexander Puchkov; 04.12.2015

Вот как я это сделал:

Я создал свой собственный DropDownListFor:

    public static MvcHtmlString TheDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> listOfValues, string placeHolder)
    {
        var model = htmlHelper.ViewData.Model;
        var metaData = ModelMetadata .FromLambdaExpression(expression, htmlHelper.ViewData);

        var tb = new TagBuilder("select");

        if (listOfValues != null)
        {
            tb.MergeAttribute("id", metaData.PropertyName);
            tb.MergeAttribute("name", metaData.PropertyName);

            if (!string.IsNullOrEmpty(placeHolder))
            {
                var option = new TagBuilder("option");
                option.MergeAttribute("value", placeHolder);

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

            foreach (var item in listOfValues)
            {
                var option = new TagBuilder("option");
                option.MergeAttribute("value", item.Value);

                var textNdata = item.Text.Split('|');

                option.InnerHtml = textNdata[0];

                if (textNdata.Length == 2)
                    option.MergeAttribute("data-name", textNdata[1]);

                if(item.Selected)
                    option.MergeAttribute("selected", "selected");

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

        return MvcHtmlString.Create(tb.ToString());
    }

Затем мой SelectListItem List создается следующим образом:

    public List<SelectListItem> EmployerList
    {
        get
        {
            return Employers.Select(x => new SelectListItem
            {
                Text = x.EAN + "|" + x.Name,
                Value = x.Id.ToString(),
                Selected = (SelectedEmployer != null && SelectedEmployer.Id == x.Id)
            }).ToList();
        }
    }
person Serj Sagan    schedule 05.11.2013