添加HTML跨越到LabelFor - MVC 3 [英] Adding html spans into a 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屋!