У меня сложная форма, которая должна использоваться как пользователями javascript, так и не-javascript.Мое приложение .NET MVC 3.
Форма содержит множество полей, которые необходимо заполнить, если они отвечают определенным образом на предыдущий вопрос.С включенным JavaScript, я могу показать или скрыть соответствующий вопрос на основе взаимодействия с пользователем.Без javascript я хотел бы добавить больше деталей к самой метке вопроса, потому что по умолчанию отображаются все вопросы (очень похоже на заполнение бумажной версии формы).
В идеале я хотел бы, чтобы меткабыть примерно таким:
<label><span class="non-js">If you were a smoker, when</span><span class="js">When</span> did you stop smoking?</label>
Таким образом, я могу отключить соответствующий текст в CSS (я надеюсь, что программа чтения с экрана может справиться с этим).
Таким образом, пользователи javascript получают:
When did you stop smoking?
и пользователи, не поддерживающие javascript, получают:
If you were a smoker, when did you stop smoking?
Мой вопрос заключается в том, как мне поступить, поскольку помощники LabelFor не допускают использование html в строке.
Обновление
Извините, я забыл одну важную информацию, поскольку мой ярлык в настоящее время заполнен [Display (Name = "Когда вы бросили курить?")]аннотация в модели.В идеале я хотел бы сохранить это здесь и иметь что-то вроде:
[Display(JS = "When", NonJS = "If you were a smoker, when", Both="did you stop smoking?")]
Возможно ли это?
Обновление 2
Хорошо, вот что у меня так далеко.Это мой атрибут:
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);
}
}
К сожалению, я застрял, так как это отображается в незашифрованном виде на экране.то есть на самом деле это выглядит так:
<span class="non-js">If you were a smoker, when</span><span class="js">When</span> did you stop smoking?
Есть ли способ изменить свойство метаданных displayName, чтобы справиться с этим?
Обновление 3 и решение
С помощью ответов и http://weblogs.asp.net/imranbaloch/archive/2010/07/03/asp-net-mvc-labelfor-helper-with-htmlattributes.aspx мне удалось получить решения, которые мне нужны:
Мой атрибут:
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));
}
Работа выполнена (в конце концов!) Спасибо всем за помощь!