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 > 0) { tagBuilder.MergeAttribute("maxlength", stringlength.MaximumLength.ToString()); } if (stringlength.MinimumLength > 0) { 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(15)]
        [Remote("CheckName", "Form")]
        public string UserName { get; set; }
        [DisplayName("密碼")]
        [Required]
        [StringLength(20,MinimumLength = 4)]
        [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(50)]
        [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模板,采用一些命名約定能更快捷的生成各種表單頁面。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM