动态生成的@ html.dropdownfor mvc3中的每个项目的工具提示

时间:2014-11-27 08:45:46

标签: jquery html asp.net-mvc tooltip dropdownlistfor

我正在使用 Razor c#在 MVC 3 中处理网络项目。

我使用@Html.DropDownListFor动态显示项目。我想为@Html.DropDownListFor的每个项目设置工具提示。

我的代码行如下

@Html.DropDownListFor(m => m.Type, new SelectList(Model.Types, "Value", "Text", Model.Type), 
new { @class = "Type"})

3 个答案:

答案 0 :(得分:0)

我对这个问题感到好奇所以只是试图实现它。我创建了一个简单的示例,并使其可以在每个选定项目上悬停显示不同的工具提示。

注意:我不是JS方面的专家,也不确定它是否是一种理想的方式。

这是我的示例代码:

MyController.cs

    public ActionResult LoadCountries()
    {
        List<SelectListItem> li = new List<SelectListItem>();
        li.Add(new SelectListItem { Text = "Select", Value = "0" });
        li.Add(new SelectListItem { Text = "India", Value = "1" });
        li.Add(new SelectListItem { Text = "Srilanka", Value = "2" });
        li.Add(new SelectListItem { Text = "China", Value = "3" });
        li.Add(new SelectListItem { Text = "Austrila", Value = "4" });
        li.Add(new SelectListItem { Text = "USA", Value = "5" });
        li.Add(new SelectListItem { Text = "UK", Value = "6" });
        ViewData["country"] = li;
        return View();
    }

<强> LoadCountries.cshtml

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="~/Scripts/TooltipDefinition.js"></script>

@{
    ViewBag.Title = "title";
}

<h2>Just For Demo</h2>

@using (Html.BeginForm())
{
    @Html.DropDownList("Countries", ViewData["country"] as List<SelectListItem>)
}

<h2 id="tooltipData"></h2>

<script type="text/javascript">

    $("#Countries > option").each(function () {
        var item = $(this).text();

        if (item !== "Select") {
            var tooltipText = MouseHoverText(item);
            $(this).attr("title", tooltipText);
        }
    });

</script>

<强> TooltipDefinition.js

var MouseHoverText = function(id) {
    switch (id) {
        case "India":
            return "You have selected India - A country full of opportunities.";
        break;
    case "Srilanka":
        return "You have selected Srilanka - God's own country.";
        break;
    default:
        return "You have selected " + id;
    }
};

我想我并没有做出与你所尝试的不同的事情。我正在捕获所有选择的项目并在加载项目时附加title属性。工具提示文本来自JS文件。你很可能通过模型​​传递它。

分享,因为它可能适合您的需要。

答案 1 :(得分:-1)

你无法开箱即用。一种方法是使用此answer中描述的 js

另一个机会是创建自己的类型,例如SelectListItem,但使用Title属性并为您的类型创建EditorTemplate。对于此变体,我提供了一些代码:

你的Templave ViewModel:

using System.Collections.Generic;
using System.Web.Mvc;

namespace Templates.ViewModels
{
    public class SelectListItemWithTitle: SelectListItem
    {
        public string Title { get; set; }
    }

    public class SelectListWithTitle
    {
        public SelectListWithTitle(IEnumerable<SelectListItemWithTitle> items)
        {
            Items = items;
        }
        public IEnumerable<SelectListItemWithTitle> Items { get; set; }
    }
}

您的EditorTemplate,您应该放在名为/Views/Shared/EditorTemplates

SelectListWithTitle.cshtml
@model Templates.ViewModels.SelectListWithTitle

@{
    Layout = null;
}

<select id="@ViewData.TemplateInfo.HtmlFieldPrefix" name="@ViewData.TemplateInfo.HtmlFieldPrefix">
    @foreach (var item in Model.Items)
    {
        <option value="@item.Value" selected="@item.Selected" title="@item.Title">@item.Text</option>
    }
</select>

你的ViewModel是这样的:

public class ViewModel
{
    public SelectListWithTitle Meal { get; set; }
}

你的控制器:

public ActionResult Index()
{
    List<SelectListItemWithTitle> selectListItemsWithTitle = new List<SelectListItemWithTitle>();
    selectListItemsWithTitle.Add(new SelectListItemWithTitle { Text = "Apple", Value = "0", Title = "Fresh" });
    selectListItemsWithTitle.Add(new SelectListItemWithTitle { Text = "Orange", Value = "1", Title = "Jussy" });
    selectListItemsWithTitle.Add(new SelectListItemWithTitle { Text = "Banana", Value = "2", Title = "Yellow", Selected = true });
    selectListItemsWithTitle.Add(new SelectListItemWithTitle { Text = "Vodka", Value = "3", Title = "Russian" });
    selectListItemsWithTitle.Add(new SelectListItemWithTitle { Text = "Beer", Value = "4", Title = "Cold" });

    SelectListWithTitle sl = new SelectListWithTitle(selectListItemsWithTitle);

    ViewModel model = new ViewModel
    {
        Meal = sl
    };
    ViewData.Model = model;

    return View();
}

您的查看索引:

@model MvcApplication1.Models.ViewModel

@Html.EditorFor(m => m.Meal)

不要忘记更改名称空间。

答案 2 :(得分:-1)

我做过类似的事情

我声明了两个类用于模型,一个用于保存下拉列表

的每个选项标记的值
public Class Report
{
  public ReportName {get; set;}
  public IList<ReportSummaryModel> AvailableReports {get; set;}
}

public class ReportSummaryModel
{
  public ReportActualName {get; set;}
  public ReportClassName {get; set;}    
  public TextField {get; set;}
  public ValueField {get; set;}
}

我想将ReportActualName和ReportClassName输出到下拉列表的选项标签中,这些值因每个选项而异。

因此我写下了HTML帮助函数

public static MvcHtmlString DropDownList<TPageModel, TSelectListModel, TProperty>(this HtmlHelper<TPageModel> htmlHelper, 
  Expression<Func<TPageModel, TProperty>> expression, IEnumerable<TSelectListModel> selectList, Expression<Func<TSelectListModel, TProperty>> textField, 
  Expression<Func<TSelectListModel, TProperty>> valueField, string optionLabel, IDictionary<string, Expression<Func<TSelectListModel, TProperty>>> optionsAttributes)

实际的功能调用如下所述

@Html.DropDownList(x => x.ReportName, 
Model.AvailableReports, 
x => x.TextField, 
x => x.ValueField, 
"-- Select --", 
new Dictionary<string, Expression<Func<ReportSummaryModel, object>>>{ {"data-name", x => x.ReportActualName}, {"data-class", x => x.ReportClassName}})

其他实用功能如下所述

public static MvcHtmlString DropDownList<TPageModel, TSelectListModel, TProperty>(this HtmlHelper<TPageModel> htmlHelper, Expression<Func<TPageModel, TProperty>> expression, IEnumerable<TSelectListModel> selectList, Expression<Func<TSelectListModel, TProperty>> textField, Expression<Func<TSelectListModel, TProperty>> valueField, string optionLabel, IDictionary<string, Expression<Func<TSelectListModel, TProperty>>> optionsAttributes)
        {
            string name = ExpressionHelper.GetExpressionText(expression);
            string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
            string defaultValue = string.Empty;
            ModelState modelState;
            if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState))
            {
                if (modelState.Value != null)
                {
                    defaultValue = (string)modelState.Value.ConvertTo(typeof(string), null /* culture */);
                }
            }
            var listItemBuilder = new StringBuilder();
            // Make optionLabel the first item that gets rendered.
            if (optionLabel != null)
            {
                listItemBuilder.AppendLine(ListItemToOption(optionLabel, string.Empty, false, null));
            }
            /* Loop through each options
             * Convert each ListItem to an <option> tag */
            foreach (var listItem in selectList)
            {
                string text = listItem.GetType()
                                      .GetProperties()
                                      .Single(p => p.Name.Equals(ClassHelper.PropertyName(textField)))
                                      .GetValue(listItem, null)
                                      .ToString();
                string value = listItem.GetType()
                                       .GetProperties()
                                       .Single(p => p.Name.Equals(ClassHelper.PropertyName(valueField)))
                                       .GetValue(listItem, null)
                                       .ToString();
                bool isSelected = value.Equals(defaultValue);
                var htmlAttributes = new Dictionary<string, string>();
                foreach (var option in optionsAttributes)
                {
                    string propertyName = ClassHelper.PropertyName(option.Value);
                    htmlAttributes.Add(option.Key, listItem.GetType()
                                                             .GetProperties()
                                                             .Single(p => p.Name.Equals(propertyName))
                                                             .GetValue(listItem, null)
                                                             .ToString());
                }
                listItemBuilder.AppendLine(ListItemToOption(text, value, isSelected, htmlAttributes));
            }
            var tagBuilder = new TagBuilder("select")
            {
                InnerHtml = listItemBuilder.ToString()
            };
            tagBuilder.MergeAttribute("name", fullName, true /* replaceExisting */);
            return new MvcHtmlString(tagBuilder.ToString(TagRenderMode.Normal));
        }

//Private method copied from mvc built in helper to generate option attribute

 internal static string ListItemToOption(string text, string value, bool isSelected, IDictionary<string, string> htmlAttributes)
        {
            var builder = new TagBuilder("option")
            {
                InnerHtml = HttpUtility.HtmlEncode(text)
            };
            if (value != null)
            {
                builder.Attributes["value"] = value;
            }
            if (isSelected)
            {
                builder.Attributes["selected"] = "selected";
            }
            if (htmlAttributes != null)
            {
                builder.MergeAttributes(htmlAttributes);
            }

            return builder.ToString(TagRenderMode.Normal);
        }


//Utility function to get property name

public class ClassHelper
    {
        public static string PropertyName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
        {
            var body = expression.Body as MemberExpression;
            if (body == null)
            {
                body = ((UnaryExpression)expression.Body).Operand as MemberExpression;
            }
            return body.Member.Name;
        }
    }

输出

&#13;
&#13;
<select name="ReportName">
 <option>--Select--</option>
 <option value="1" data-name="NameA" data-class="classA">A</option>                  
    <option value="2" data-name="NameB" data-class="classB">B</option>                  
    <option value="3" data-name="NameC" data-class="classC">C</option>                  
    <option value="4" data-name="NameD" data-class="classD">D</option>                  
</select>
&#13;
&#13;
&#13;