2014-01-08 98 views
3

我期待产生的代码是类似于:扩展HTML辅助

<div class="form-group"> 
    <label for="email">Email address</label> 
    <input type="email" class="form-control" id="email" placeholder="Enter email"> 
</div> 

使用这样的事情:

@Html.LabelledTextBoxFor(model => model.EmailAddress) 

凡标注文本得到来自model.EmailAddress

衍生这将使用数据注释来完成,例如

[Displayname("Email Address] 

完成此操作的最佳方法是什么?

这会影响使用jquery val自动生成客户端JS验证吗?

+0

你想操纵JavaScript的标签? –

+0

不,我想扩展C#Html帮助程序 – LmC

+0

这个http://msdn.microsoft.com/tr-tr/library/system.componentmodel.dataannotations.displayattribute(v = vs.110)已经有一个显示属性。 aspx –

回答

0

数据注解走在上面属性的视图模型:

[DisplayName("Email Address")] 
public string EmailAddress { get; set; } 

然后,在你看来,你有这样的事情:

@Html.LabelFor(m => m.EmailAddress) 
@Html.TextBoxFor(m => m.EmailAddress, new { @placeholder="Enter email", @class="form-control", @id="email" }) 
+0

我明白,如上所述,主要问题是不希望必须同时执行@ Html.LabelFor和TextBox。 我想制作自己的HTML助手,它将这两者结合起来并将它们包装在DIV中,以匹配问题中的给定代码。 我知道它现在听起来很愚蠢,但如果你想到它,一旦我得到这个工作,我将能够整合引导和C#很容易。 – LmC

+0

啊,我相信已经有这个答案了。你看过这个吗? http://stackoverflow.com/questions/5824124/html5-placeholders-with-net-mvc-3-razor-editorfor-extension – WhiteRuski

5

我写了一个扩展方法,也许这可能有所帮助:

public static MvcHtmlString LabelledTextBoxFor<TModel, TResult>(this HtmlHelper<TModel> html, Expression<Func<TModel, TResult>> expression) 
{ 
    ExpressionType type = expression.Body.NodeType; 
    if (type == ExpressionType.MemberAccess) 
    { 
     MemberExpression memberExpression = (MemberExpression) expression.Body; 
     var propName = memberExpression.Member.Name; 

     var member = memberExpression.Member as PropertyInfo; 

     var attributes = member.GetCustomAttributes(); 

     StringBuilder sb = new StringBuilder(); 
     foreach (var attribute in attributes) 
     { 
      if (attribute is DisplayAttribute) 
      { 
       DisplayAttribute d = attribute as DisplayAttribute; 
       var displayName = d.Name; 
       sb.Append("<div class=\"form-group\">"); 
       sb.AppendFormat("<label for=\"{0}\">{1}</label>", propName, displayName); 
       sb.AppendFormat(
         "<input type=\"email\" class=\"form-control\" id=\"{0}\" placeholder=\"Enter email\">", 
         propName); 
       sb.Append("</div>"); 
       return MvcHtmlString.Create(sb.ToString()); 
      } 
     } 

    } 
     return MvcHtmlString.Create(""); 
} 

您可以使用默认显示属性来指定显示名称。无需定制attributes.And你可以使用这个扩展这样的:

@Html.LabelledTextBoxFor(model => model.EmailAddress) 

注:我曾尝试自己和它的正常工作。

更新:更简单的版本

public static MvcHtmlString LabelledTextBoxFor2<TModel, TResult>(this HtmlHelper<TModel> html, Expression<Func<TModel, TResult>> expression) 
    { 
     ExpressionType type = expression.Body.NodeType; 
     if (type == ExpressionType.MemberAccess) 
     { 
      var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 
      var displayName = metadata.DisplayName; 
      var propName = metadata.PropertyName; 

      StringBuilder sb = new StringBuilder(); 

      sb.Append("<div class=\"form-group\">"); 
      sb.AppendFormat("<label for=\"{0}\">{1}</label>", propName, displayName); 
      sb.AppendFormat(
         "<input type=\"email\" class=\"form-control\" id=\"{0}\" placeholder=\"Enter email\">", 
         propName); 
      sb.Append("</div>"); 
      return MvcHtmlString.Create(sb.ToString()); 
     } 

     return MvcHtmlString.Create(""); 
    } 
+1

+1,但你可以简化:'var metadata = ModelMetadata.FromLambdaExpression(expression,helper。 ViewData);'。这会给你一个包含显示名称等信息的抽象。 –

+0

对,我用过它。只是想确保这个属性有显示属性。我用简化版本更新了我的答案 –

1

我会用@Html.EditorFor模板。因此,在您的MVC项目中使用名称EmailAddress.cshtmlViews /共享中创建EditorTemplates文件夹 - 它会在模型​​中定义的每个[DataType(DataType.EmailAddress)]中显示此模板。

所以:EmailAddress.cshtml应该是某事像这样:

<div class="form-group"> 
<label for="email">@Html.LabelFor(x => x)</label> 
@Html.TextBoxFor(x => x, new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark }) 
</div> 

型号应该是这样的:

public class SomeModel { 

    [DataType(DataType.EmailAddress)] 
    [Display(Name="Some string for LabelFor", Prompt = "Placeholder in input"] 
    public string SomeEmail { get; set; } 
} 

注意这里,我用显示屏元数据的Prompt属性,我通过ViewData.ModelMetadata.WatermarkEmailAddress.cshtml链接到占位符。 Html.LabelFor将始终从Display中获取属性名称,并且需要DataType以在EditorTemplates和model属性之间进行链接。

,并通过使用

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

页面上,在您使用SomeMode模型调用所有这“神奇”。

我希望这是有道理的。

1

无需重新发明轮子。退房TwitterBootstrapMVC

的代码你会写作将类似于下面:

@Html.Bootstrap().FormGroup().TextBoxFor(model => model.EmailAddress).Placeholder("Enter email") 

免责声明: 我TwitterBootstrapMVC的authot。

用于Bootstrap 3的TwitterBootstrapMVC不是免费的。在网站上查看详情。

+2

事情是,它必须是免费的,由于项目的性质 – LmC