TextBoxFor控件的扩展---Bootstrap在mvc上的应用
TextBoxFor控件的问题:
1:自带了样式,再用bootstrap样式会有冲突。
2:要加水印,js事件,限制输入长度比较麻烦。
因此需要对textboxfor控件进行扩展。
目标:
1:能使用bootstrap样式。
2:能复用mvc的验证。
3:可以方便的添加水印。
4:能限制输入字符的长度。
5:采用一些命名约定,使用扩展控件。(说白了,就是日期类型的直接给上边加上调用日期控件的调用。)
解决方案
最容易想到的解决办法就是直接写个扩展方法,进行字符串拼接生成控件。使用的时候:@BootStrap.TextBoxFor(u=>u.Email)
最终生成:
<input class="form-control" data-val="true" data-val-length="字段 邮箱 必须是最大长度为 50 的字符串。" data-val-length-max="50" data-val-regex="字段 邮箱 必须与正则表达式“.+”匹配。" data-val-regex-pattern=".+" data-val-required="邮箱 字段是必需的。" id="Email" maxlength="50" name="Email" type="text" value="taibaizhou@163.com"></input>
<span class="field-validation-valid help-block" data-valmsg-for="Email" data-valmsg-replace="true"></span>
实现时候,悲催了。发现很难直接获取属性的验证信息,难道要自己再写反射,读取特性。生成对应的验证信息。
另一条路,借助mvc的htmlhelper来完成了。
public static MvcHtmlString BsTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,string css="", string placeholder="")
{
TagBuilder tagBuilder = new TagBuilder("input");
ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
//tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(ExpressionHelper.GetExpressionText(expression), metadata));
string name = ExpressionHelper.GetExpressionText(expression);
//var vas = htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata);
htmlHelper.ValidateFor(expression);
tagBuilder.MergeAttribute("name",name);
tagBuilder.GenerateId(name);
tagBuilder.MergeAttribute("type","text");
//核心代码,直接通过这个方法可以获取属性上的验证信息,如:“data-val= ....”。有一点要注意,在一个属性上,调用了这个方法完成后。mvc底层代码会自动释放这个验证对象。也就是说,一个属性的输入文本框只会第一个上边会生成相关的验证。
var vas = htmlHelper.GetUnobtrusiveValidationAttributes(name,metadata);
if (!string.IsNullOrEmpty(placeholder)) { tagBuilder.MergeAttribute("placeholder",placeholder); }
//string类型,看有没长度限制,如果有,增加maxlength,minlength
if (metadata.ModelType == typeof (string))
{
var len = metadata.ContainerType.GetProperty(name).GetCustomAttribute(typeof(StringLengthAttribute));
if (len != null)
{
var stringlength = (StringLengthAttribute) len;
if (stringlength.MaximumLength > )
{
tagBuilder.MergeAttribute("maxlength", stringlength.MaximumLength.ToString());
}
if (stringlength.MinimumLength > )
{
tagBuilder.MergeAttribute("minlength", stringlength.MinimumLength.ToString());
}
}
}
//如果model值不为,null,进行赋值。
if (metadata.Model != null)
{
todo:还要完善。
tagBuilder.MergeAttribute("value",metadata.Model.ToString());
}
tagBuilder.MergeAttributes(vas);
tagBuilder.AddCssClass("form-control");
if (!string.IsNullOrEmpty(css))
{
tagBuilder.AddCssClass(css);
}
//约定,属性名以day或者date结束的属性为日体,为其增加日期选择功能。
if (name.ToLower().EndsWith("day") || name.ToLower().EndsWith("date"))
{
tagBuilder.MergeAttribute("onclick", "WdatePicker()");
}
return new MvcHtmlString(tagBuilder.ToString());
}
最终实现效果:

View部分代码:
<div class="form-group">
@Html.BsLabelFor(model => model.Email)
<div class="col-xs-10">
@*@Html.TextBoxFor(model => model.Email, new { @class = "form-control" })*@
@Html.BsTextBoxFor(model=>model.Email)
@Html.ValidationMessageFor(model => model.Email, "", new { @class = "help-block" }) </div>
</div>
<div class="form-group">
@Html.BsLabelFor(model => model.Salary)
<div class="col-xs-2 input-group" >
<div class="input-group-addon">$</div>
@Html.BsTextBoxFor(model => model.Salary)
<div class="input-group-addon">.00</div>
</div><div class="col-xs-8">
@Html.ValidationMessageFor(model => model.Salary, "", new { @class = "help-block" })
</div>
</div>
<div class="form-group">
@Html.BsLabelFor(model => model.Code)
<div class="col-xs-2">
@Html.BsTextBoxFor(model => model.Code)
</div><div class="col-xs-8">
@Html.ValidationMessageFor(model => model.Code, "", new { @class = "help-block" })
</div>
</div>
<div class="form-group">
@Html.BsLabelFor(model => model.BirthDay)
<div class="col-xs-2 input-group">
@Html.BsTextBoxFor(model => model.BirthDay)<div class="input-group-addon" onclick="WdatePicker({ el: 'BirthDay' })">
<span class="glyphicon glyphicon-th"></span>
</div>
</div><div class="col-xs-8">
@Html.ValidationMessageFor(model => model.BirthDay)
</div>
</div>
viewModel代码:
public class VerifyModel
{
public Guid Id { get; set; }
[DisplayName("用户名")]
[Required]
[StringLength()]
[Remote("CheckName", "Form")]
public string UserName { get; set; }
[DisplayName("密码")]
[Required]
[StringLength(,MinimumLength = )]
[DataType(DataType.Password)]
public string PassWord { get; set; }
[DataType(DataType.Password)]
[System.ComponentModel.DataAnnotations.Compare("PassWord", ErrorMessage = "两次输入密码不一致")]
[DisplayName("确认密码")]
public virtual string ConfirmPassWord { get; set; }
[StringLength()]
[DisplayName("邮箱")]
[Required]
[DataType(DataType.EmailAddress)]
[RegularExpression(@".+")]
public string Email { get; set; }
[RegularExpression(@"1\d{10}", ErrorMessage = "请输入正确的手机号码")]
[DisplayName("手机")]
[Required]
public string Phone { get; set; }
[DisplayName("薪水")]
[Required]
public decimal Salary { get; set; }
[RegularExpression(@"d{6}", ErrorMessage = "邮编为六位数字")]
[DisplayName("邮编")]
[Required]
public string Code { get; set; }
[DisplayName("生日")]
[Required]
public DateTime BirthDay { get; set; }
}
最后:
配合T4模板,采用一些命名约定能更快捷的生成各种表单页面。
TextBoxFor控件的扩展---Bootstrap在mvc上的应用的更多相关文章
- MvcPager分页控件以适用Bootstrap
随笔- 9 文章- 0 评论- 33 修改MvcPager分页控件以适用Bootstrap 效果(含英文版,可下载) 软件开发分页效果必不可少,对于Asp.Net MVC 而言,MvcPag ...
- 验证控件插图扩展控件ValidatorCalloutExtender(用于扩展验证控件)和TextBoxWatermarkExtender
<asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptMan ...
- (转)C# WinForm中 获得当前鼠标所在控件 或 将窗体中鼠标所在控件名显示在窗体标题上
原文地址:http://www.cnblogs.com/08shiyan/archive/2011/04/14/2015758.html /********************** * 课题:将窗 ...
- 使用NeatUpload控件实现ASP.NET大文件上传
使用NeatUpload控件实现ASP.NET大文件上传 一般10M以下的文件上传通过设置Web.Config,再用VS自带的FileUpload控件就可以了,但是如果要上传100M甚至1G的文件就不 ...
- 使用input:file控件在微信内置浏览器上传文件返回未显示选择的文件
使用input:file控件在微信内置浏览器上传文件返回未显示选择的文件 原来的写法: <input type="file" accept="image/x-png ...
- 【C#】使用IExtenderProvider为控件添加扩展属性,像ToolTip那样
申明: - 本文适用于WinForm开发 - 文中的“控件”一词是广义上的说法,泛指包括ToolStripItem.MenuItem在内单个界面元素,并不特指继承自Control类的狭义控件 用过To ...
- WPF中查找控件的扩展类
在wpf中查找控件要用到VisualTreeHelper类,但这个类并没有按照名字查找控件的方法,于是搜索网络,整理出下面这个类,感觉用起来很是方便. 贴出来,供大家参考. /// <summa ...
- WPF之花式控件功能扩展
文章默认你已经入门WPF了 WPF日常开发,经常遇到默认的控件功能不满足需求,怎么办? No1. 自定义控件模板 平时开发中,经常遇到比较"俗"的需求,嫌弃控件默认的样子. ...
- asp.net ajax控件tab扩展,极品啊,秒杀其它插件
说明:asp.net ajax控件tab要设置width和height,而且在线文本编辑器放能够放入tab中,也必须是asp.net的控件型在线文本,例如fckeditor,下面是我设置好的配置. & ...
随机推荐
- html5+css3实现跑动的爱心/动态水滴效果[原创][5+3时代]
大风起兮云飞扬,安得猛士兮走四方!html5+css3,不学不行. 做web开发已经有好几年了,见证了太多语言的崛起和陨落. 其实作为一个程序员最苦逼的事情莫过于每天要不停的追赶各大公司新出的框架和语 ...
- gcc编译参数-fPIC的一些问题
gcc编译参数-fPIC的一些问题 (2012-07-26 15:41:08) 转载▼ 标签: linux compiler gcc -fpic it 分类: NSN_BspDriver ppc_85 ...
- corefile 设置
程序运行的过程中,可能会因为一些隐藏的bug导致崩溃,为了在出问题时,及时记录所在环境的情况,所以要设置core文件的产生.其实其本质就是把进程的内存保存到文件中去. 1.core文件的生成开关和大小 ...
- 在VMware上安装CentOS-6.5 minimal - 安装VMware Tools
由于CentOS-6.5 minimal很多工具都默认没有安装,安装VMwareTools需要用到Perl,所以老伯建议先配置好网络再接着安装. 网络配置方法可以参考在VMware上安装CentOS- ...
- Sql server2012连接Sql server 2008时出现的问题:已成功与服务器建立连接,但在登陆过程中发生错误。(provider:SSL Provider,error:0-接收到的消息异常,或格式不正确。)
以前连接是正常的,就这两天连不上了.(没有耐心的直接看末尾解决办法) 错误消息如下: 1.尝试读取或写入受保护的内存.这通常指示其他内存已损坏.(System.Data) 2.已成功与服务器建立连接, ...
- 一起来啃书——PHP看书
形式所迫,不得不开展android的学习,PHP这边也开始了啃书的日子.两部500+的书,45天够不,有点忙有点忙... 早上的胃胀,简直是一记闷棍,长点儿记性吧........ 1.PHP+MYSQ ...
- AC日记——石头剪子布 openjudge 1.7 04
04:石头剪子布 总时间限制: 1000ms 内存限制: 65536kB 描述 石头剪子布,是一种猜拳游戏.起源于中国,然后传到日本.朝鲜等地,随着亚欧贸易的不断发展它传到了欧洲,到了近现代逐渐风 ...
- 今天在看UWP蓝牙的例子
private async void InitializeRfcommServer() { ListenButton.IsEnabled = false; DisconnectButton.IsEna ...
- MYSQL基础知识总结
!注释方式 # -- 单行 /* */ 多行 1.SELECT column1,column2,column3 FROM tablename WHERE id <= 5 ...
- tyvj[1089]smrtfun
描述 现有N个物品,第i个物品有两个属性A_i和B_i.在其中选取若干个物品,使得sum{A_i + B_i}最大,同时sum{A_i},sum{B_i}均非负(sum{}表示求和). 输入格式 ...