添加HTML跨越到LabelFor - MVC 3 [英] Adding html spans into a LabelFor - MVC 3

查看:99
本文介绍了添加HTML跨越到LabelFor - MVC 3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个复杂的形式,这需要通过JavaScript和非JavaScript的用户使用。我的应用程序是.NET MVC 3。

I've got a complicated form, which needs to be used by both javascript and non-javascript users. My application is .NET MVC 3.

形式有很多领域,其中有,如果他们回答到previous问题特定的方式来填充的。随着启动Javascript,我能够显示或隐藏基于用户互动的相关问题。由于没有JavaScript的,我想更多的细节添加到这个问题标签本身,因为默认情况下,所有的问题都显示(很像形式的纸质版填充)。

The form has plenty of fields, which have to be filled in if they answer a particular way to a previous question. With javascript enabled, I'm able to show or hide the relevant question based on a user interaction. With no javascript I would like to add more detail to the question label itself because by default all of the questions are shown (much like filling in a paper version of the form).

我非常希望的标签是这样的:

Ideally I would like the label to be something like:

<label><span class="non-js">If you were a smoker, when</span><span class="js">When</span> did you stop smoking?</label>

这样我可以关掉在CSS中的有关内容(我希望一个屏幕阅读器可以应对这一切)。

This way I can switch off the relevant text in CSS (I'm hoping a screenreader can cope with this).

所以,JavaScript的用户获得:

So javascript users get:

When did you stop smoking?

和非JavaScript的用户获得:

and non-javascript users get:

If you were a smoker, when did you stop smoking?

我的问题是我怎么会去这样做,因为LabelFor佣工不允许在字符串中的HTML。

My question is how would I go about doing this, as LabelFor helpers don't allow html in the string.

更新

对不起,我忘了信息的一个重要的一点,在我的标签目前正由一个人口[显示(名称=你什么时候戒烟?)]注释在模型中。 Idelly我想在这里保持这和有类似:

Sorry, I forgot one crucial bit of info, in that my label is currently being populated by a [Display(Name = "When did you stop smoking?")] annotation in the model. Idelly I would like to keep this here and have something like:

[Display(JS = "When", NonJS = "If you were a smoker, when", Both="did you stop smoking?")]

这可能吗?

更新2

确定这里就是我这么远。这是我的属性:

OK here's what I've got so far. This is my attribute:

public class MultipleDisplayNameAttribute : Attribute, IMetadataAware
{
    public string CustomerDisplayName { get; set; }
    public string CustomerJSAlternative { get; set; }
    public string CustomerNonJSAlternative { get; set; }

    public void OnMetadataCreated(ModelMetadata metadata)
    {
        string jsPart;
        string nonJsPart;
        jsPart = (CustomerJSAlternative != null) ? String.Format("<span class='spnJs'>{0}</span>", CustomerJSAlternative) : "";
        nonJsPart = (CustomerNonJSAlternative != null) ? String.Format("<span class='spnNonJs'>{0}</span>", CustomerNonJSAlternative) : "";
        metadata.DisplayName = String.Format("{0}{1}{2}", jsPart, nonJsPart, CustomerDisplayName);
    }
}

不幸的是,因为这是显示在屏幕上unen codeD我现在卡住了。即它实际上是走出这样的屏幕上:

Unfortunately I'm now stuck as this is displayed unencoded on the screen. i.e. it is actually coming out like this on screen:

<span class="non-js">If you were a smoker, when</span><span class="js">When</span> did you stop smoking?

有没有办法来改变显示名元数据属性来应对呢?

Is there any way to change the displayName metadata property to cope with this?

Update 3及解决方案

随着答案的帮助和<一个href=\"http://weblogs.asp.net/imranbaloch/archive/2010/07/03/asp-net-mvc-labelfor-helper-with-htmlattributes.aspx\" rel=\"nofollow\">http://weblogs.asp.net/imranbaloch/archive/2010/07/03/asp-net-mvc-labelfor-helper-with-htmlattributes.aspx我设法解决方案我是后:

With the help of the answers and http://weblogs.asp.net/imranbaloch/archive/2010/07/03/asp-net-mvc-labelfor-helper-with-htmlattributes.aspx I managed to get the solutions I was after:

我的属性:

public class MultipleDisplayNameAttribute : Attribute, IMetadataAware
{
    public string CustomerDisplayName { get; set; }
    public string CustomerJSAlternative { get; set; }
    public string CustomerNonJSAlternative { get; set; }

    public void OnMetadataCreated(ModelMetadata metadata)
    {
        metadata.AdditionalValues["JS"] = (CustomerJSAlternative != null) ? String.Format("<span class='spnJs'>{0}</span>", CustomerJSAlternative) : "";
        metadata.AdditionalValues["NoJS"] = (CustomerNonJSAlternative != null) ? String.Format("<span class='spnNonJs'>{0}</span>", CustomerNonJSAlternative) : "";
        metadata.DisplayName = CustomerDisplayName;
    }
}

我的助手:

    public static MvcHtmlString JsAndNonJsCheckFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
        HtmlString jsLabel = new HtmlString("");
        HtmlString noJsLabel = new HtmlString("");
        string htmlFieldName = ExpressionHelper.GetExpressionText(expression);

        string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
        if (String.IsNullOrEmpty(labelText))
            return MvcHtmlString.Empty;


        if(metadata.AdditionalValues.ContainsKey("JS"))
            jsLabel = new HtmlString((string)metadata.AdditionalValues["JS"]);


        if (metadata.AdditionalValues.ContainsKey("NoJS"))
            noJsLabel = new HtmlString((string)metadata.AdditionalValues["NoJS"]);

        TagBuilder tagBuilder = new TagBuilder("label");
        tagBuilder.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
        tagBuilder.InnerHtml = String.Format("{0}{1}{2}", jsLabel, noJsLabel, labelText);

        return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
    }

作业已完成(最终!)谢谢大家的帮助!

Job done (eventually!) Thanks for everyone's help!

推荐答案

您目前的问题是多么 LabelFor 的作品。这是反编译源$ C ​​$为 LabelFor C(从MVC2实际源可能是更好的,并且是免费提供下载。):

Your current problem is just how LabelFor works. This is the decompiled source code for LabelFor (from MVC2. The actual source is probably nicer, and is freely available for download):

    public static MvcHtmlString LabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
      return LabelExtensions.LabelHelper((HtmlHelper) html, ModelMetadata.FromLambdaExpression<TModel, TValue>(expression, html.ViewData), ExpressionHelper.GetExpressionText((LambdaExpression) expression));
    }

    internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName)
    {
      string str = metadata.DisplayName;
      if (str == null)
      {
        string propertyName = metadata.PropertyName;
        if (propertyName == null)
          str = Enumerable.Last<string>((IEnumerable<string>) htmlFieldName.Split(new char[1]
          {
            '.'
          }));
        else
          str = propertyName;
      }
      string innerText = str;
      if (string.IsNullOrEmpty(innerText))
        return MvcHtmlString.Empty;
      TagBuilder tagBuilder = new TagBuilder("label");
      tagBuilder.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
      tagBuilder.SetInnerText(innerText);
      return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
    }
  }

您可以基本上复制此code,改变方法的名称,并更改code的第二最后一行是:

You could basically copy this code, change the method name, and change the second last line of code to be:

tagBuilder.InnerHtml(innerText);

和它,你将有一个工作的解决方案,它不会逃避你的HTML。

And it you will have a working solution which doesn't escape your HTML.

这篇关于添加HTML跨越到LabelFor - MVC 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆