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,下面是我设置好的配置. & ...
随机推荐
- eclipse常用配置
一. 手动方式安装svn插件 1. 根据本地的svn客户端的版本,到http://subclipse.tigris.org/ 下载eclipse对应版本的svn插件包 注:装eclipse里面的svn ...
- C语言 复制字符串 malloc
今天在看前辈的代码,对其中字符串复制有时候直接把指针赋给另一个指针,有的malloc一个内存,然后把整个字符串的值拷贝过来,有点费解,就研究了一下,会了之后发现也没什么奥秘,其实很简单,不过还是记录一 ...
- 使用bakefile编译C工程代码
前言 最近有个想法,想把ineedle整体架构从头自己编写代码来实现一下,来加深对iNeedle系统的理解,同时加强Linux + C相关知识.由于iNeedle系统的庞大,只能是先把框架搭起来,根据 ...
- Android getevent
详细用法如下: 源码复制打印? Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] ...
- if_nametoindex可以检查网卡名称是否有效
NAME if_nametoindex, if_indextoname, if_nameindex, if_freenameindex - convert interface index to nam ...
- setTimeout()与setInterval()——走马灯效果
JavaScript中的setTimeout()与setInterval()都是指延时执行某一操作. 但setInterval()指每隔指定时间执行某操作,会循环不断地执行该操作:setTimeout ...
- Mac brew命令
一.简介 Brew又叫Homebrew,是MAC中的一款软件包管理工具,通过brew可以很方便的在MAC中安装软件或者是卸载软件. 二.安装 ruby -e "$(curl -fsSL ht ...
- 新手必学的java报表开发工具FineReport实用技巧
1.在制作模板时,如何将报表中的值传递到超链接网页呢? 在项目中以frame方法把F1.CPT放到项目的页面中,对F1.CPT做网络报表超链接F2.CPT,然后在F2.cpt页面中,做个超链接的网页, ...
- 2015 Selenium大会
9月8号到10号三天在俄勒冈州的波特兰召开了Selenium Conference 2015,分享的演讲很多,视频也放出来了,做了下搬运工,传到优酷 简介: A conference that bri ...
- UESTC-第五届ACM趣味程序设计竞赛第四场(正式赛)--不完全解题报告
比赛链接: http://acm.uestc.edu.cn/contest.php?cid=230 A.Police And The Thief ---UESTC 1913 简单博弈,先假设在警察先走 ...