jquery.validate[.unobtrusive]和Bootstrap實現tooltip錯誤提示

来源:http://www.cnblogs.com/newton/archive/2016/10/29/6011006.html
-Advertisement-
Play Games

類似的文章園子里已有,請看這裡,個人感覺稍顯複雜,日前也打算寫一個簡單的給項目用,一些關鍵點記錄於此。最終效果如下: 後端使用Asp.net mvc5,前端框架有:jquery.validate、jquery.validate.unobtrusive、requirejs、Bootstrap,都是當前 ...


類似的文章園子里已有,請看這裡,個人感覺稍顯複雜,日前也打算寫一個簡單的給項目用,一些關鍵點記錄於此。最終效果如下:

後端使用Asp.net mvc5,前端框架有:jquery.validate、jquery.validate.unobtrusive、requirejs、Bootstrap,都是當前最/較新版本。jquery.validate就不用說了,目前比較流行的前端校驗組件;jquery.validate.unobtrusive基於jquery.validate,是為了配合Asp.net mvc,微軟自己寫的,NuGet下可查找Microsoft.jQuery.Unobtrusive.Validation安裝,具體怎麼用請繼續往下看。

首先在後臺我們定義實體類:

/// <summary>
/// 廠家信息
/// </summary>
public class Manufacturer : OperatedModel
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
    /// <summary>
    /// 信用代碼/註冊號
    /// </summary>
    [Required(ErrorMessage = "信用代碼/註冊號不能為空")]
    [MaxLength(30)]
    public string EnterpriseNo { get; set; }
    /// <summary>
    /// 企業名稱
    /// </summary>
    [Required(ErrorMessage = "企業名稱不能為空")]
    public string EnterpriseName { get; set; }
    /// <summary>
    /// 註冊地址
    /// </summary>
    [Required(ErrorMessage = "註冊地址不能為空")]
    public string RegisteredAddress { get; set; }
    /// <summary>
    /// 法人
    /// </summary>
    [Required(ErrorMessage = "法人不能為空")]
    public string ArtificialPerson { get; set; }
    /// <summary>
    /// person in charge 負責人
    /// </summary>
    [Required(ErrorMessage = "負責人不能為空")]
    public string PIC { get; set; }
    [Required(ErrorMessage = "手機號不能為空")]
    [RegularExpression(RegexLib.Mobile, ErrorMessage = "手機號碼格式不正確")]
    public string Mobile { get; set; }
        
    [EmailAddress]
    public string Email { get; set; }
    /// <summary>
    /// 商鋪號
    /// </summary>
    public string ShopNumber { get; set; }
    /// <summary>
    /// 店鋪管理員姓名
    /// </summary>
    public string StoreManagerName { get; set; }
    /// <summary>
    /// 店鋪管理員聯繫方式
    /// </summary>
    [RegularExpression(RegexLib.Mobile, ErrorMessage="手機號碼格式不正確")]
    public string StoreManagerNumber { get; set; }
    /// <summary>
    /// 主要執照, 三證合一營業執照
    /// </summary>
    public string MainLicence { get; set; }
    /// <summary>
    /// json, 其他執照,如生產許可證
    /// </summary>
    public string OtherLicence { get; set; }
    /// <summary>
    /// 入駐日期
    /// </summary>
    [Required(ErrorMessage = "入駐日期不能為空")]
    public DateTime EnterDate { get; set; }
    /// <summary>
    /// 離場日期
    /// </summary>
    [Required(ErrorMessage = "截止日期不能為空")]
    public DateTime QuitDate { get; set; }
    /// <summary>
    /// 廠家可提現餘額
    /// </summary>
    public decimal Balance { get; set; }
}
實體定義

實體各屬性上面有Attribute形式的校驗規則,當用戶提交一個Model到後端Action時,MVC框架會據此自動幫我們完成校驗工作,於是後端開發就很開心。然而在數據提交之前,前端也有必要進行第一輪的校驗,如果使用jquery.validate,那麼需要在js或標簽里再寫一遍類似的規則,能不能復用後端已有的代碼呢?我們以屬性EnterpriseNo為例,在cshtml中寫:

@Html.TextBoxFor(m => m.BasicInfo.EnterpriseNo, new { placeholder = "必填項", @class = "form-control" })

最終生成的html如下:

<input class="form-control" data-val="true" data-val-maxlength="欄位 EnterpriseNo 必須是最大長度為“30”的字元串或數組類型。" data-val-maxlength-max="30" data-val-required="信用代碼/註冊號不能為空" id="BasicInfo_EnterpriseNo" name="BasicInfo.EnterpriseNo" placeholder="必填項" value="" data-original-title="" title="" type="text">

標簽裡面自動加上了很多data-開頭的屬性,data-val表示該控制項需要校驗,其它data-開頭的就是一系列校驗規則和失敗時的錯誤信息,錯誤信息可以自定義,否則框架會給你生成類如“欄位 EnterpriseNo 必須是最大長度為30的字元串或數組類型。”這種機器翻譯語言。當然這些屬性jquery.validate是不認的,要讓jquery.validate認識,就需要jquery.validate.unobtrusive出馬了。

現在我們來說這些js如何配合使用。

新版本的jquery.validate已經支持AMD模式,所以可以直接使用requirejs載入,jquery.validate.unobtrusive則不行,需要shim配置,代碼:

require.config({
            baseUrl: '/scripts',
            paths: {
                "jquery": 'jquery-2.2.3.min',
                "knockout":'knockout-3.4.0',
                "bootstrap":'../components/bootstrap/3.3.6/js/bootstrap.min','validate':'jquery.validate',
                'validateunobtrusive':'jquery.validate.unobtrusive.min'
            },
            shim : {
                'bootstrap' : {
                    deps : [ 'jquery' ],
                    exports : 'bootstrap'
                },
                'validateunobtrusive':{
                    deps:['validate'],
                    exports: 'validateunobtrusive'
                }
            }
        });

配置好後,在頁面中require,此時點擊submit按鈕提交表單,各js就開始作用了。但是除了焦點會落到第一個校驗失敗的控制項上,似乎並沒有其它效果,連jquery.validate預設的在控制項後面展示錯誤信息(errorPlacement函數)都沒有了,are you kidding me?其實這是因為jquery.validate.unobtrusive覆蓋了errorPlacement配置項(看源碼中的attachValidation函數),對我們來說反而省了一道工序。由於tooltip的html標記是由bootstrap動態生成的,所以errorPlacement並不適合我們,參考本文開頭的鏈接,選擇覆寫showErrors函數,核心代碼如下(tooltipvalidator.js):

 1 define(['validateunobtrusive'], function () {
 2 
 3     function TooltipValidator() {}
 4 
 5     TooltipValidator.prototype = {
 6         init: function (validatorOptions, tooltipOptions) {
 7             tooltipOptions = tooltipOptions || {};
 8             validatorOptions = validatorOptions || {};
 9 
10             this._tooltipOptions = $.extend({}, {
11                 placement: 'top'
12             }, tooltipOptions, { animation: false });
13 
14             this._validatorOptions = $.extend({}, {
15 
16                 //errorPlacement: function (error, element) {
17                 //    // do nothing
18                 //},
19 
20                 showErrors: function (errorMap, errorList) {
21                     for (var i = 0; i < this.successList.length; i++) {
22                         var success = this.successList[i];
23                         $(this.successList[i]).tooltip('destroy');
24                         $(this.successList[i]).parents('div.form-group').removeClass('has-error');
25                     }
26                     for (var i = 0; i < errorList.length; i++) {
27                         var errorElement = $(errorList[i].element);
28                         errorElement.parents('div.form-group').addClass('has-error');
29                         errorElement.attr('data-original-title', errorList[i].message).tooltip('show');
30                     }
31                 },
32 
33                 submitHandler: function (form) {
34                     return false;
35                 }
36 
37             }, validatorOptions)
38 
39             this._configTooltip();
40             this._configValidator();
41         },
42 
43         _configTooltip: function () {
44             $('[data-val="true"]').tooltip(this._tooltipOptions);
45         },
46 
47         _configValidator: function () {
48             $.validator.setDefaults(this._validatorOptions);
49             $.validator.unobtrusive.parse(document);
50         }
51     }
52 
53     return new TooltipValidator();
54 });

這樣我們就可以在require回調函數中執行tooltipvalidator.init,不需要另外再寫邏輯,於是前端同學也開心的笑了。這裡還有一處需要註意,大家看到第49行代碼,這是初始化jquery.validate.unobtrusive的步驟。原本jquery.validate.unobtrusive在其代碼中已經有$(function () { $jQval.unobtrusive.parse(document); });但是由於$.ready會在Dom元素載入完成後(題外話:不是渲染完成)就執行,因此它會在tooltipvalidator有機會_configValidator之前完成,導致咱們的配置項無效(如果是在單頁無刷新應用中,會發現之後再次載入局部頁時,配置項有效了,因為$.ready只在初次載入的時候執行,而require回調會每次載入都執行)。有兩種解決方法:1、讓jquery.validate.unobtrusive依賴tooltipvalidator;2、移除jquery.validate.unobtrusive中的$jQval.unobtrusive.parse(document);這裡選擇第2種。

 

很久沒寫博文,這次是寫的最快的了,20分鐘搞定,後續可能會有修改。

轉載請註明本文出處:http://www.cnblogs.com/newton/p/6011006.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 標記名稱:flink [標簽簡介] [功能說明]:用於獲取友情鏈接,其對應後臺文件為"includetaglibflink.lib.php". [適用範圍]:全局標記,適用V55,V56,V57。 [參數說明]: [1]type:鏈接類型,值: a. textall 全部用文字顯示; b. text ...
  • // 首碼形式:增加然後取回值UPInt& UPInt::operator++(){ *this += 1; // 增加 return *this; // 取回值}// postfix form: fetch and incrementconst UPInt UPInt::operator++(in ...
  • 如下記錄一次作業: 很顯然,我這個應該屬於二逼青年版,會在以後更新文藝青年版的答案。 1、模仿sed,一個文件中,用新字元串替換老字元串。 2、查找、添加、刪除特定的內容 ...
  • 我的博客園博文地址:http://www.cnblogs.com/tenglongwentian/ Lucene,最新版是Lucene6.2.1,匹配的jdk版本是1.8正式版。這裡用jdk7最後一版,所以用Lucene5.3.3。 新建一個maven項目,如果不會可以參考前面的博文,前面的博文有專 ...
  • 以太坊是區塊鏈開發領域最好的編程平臺,而truffle是以太坊(Ethereum)最受歡迎的一個開發框架,這是我們第一篇區塊鏈技術文章介紹truffle的原因,實戰是最重要的事情,這篇文章不講原理,只搭建環境,運行第一個區塊鏈程式(Dapp)。 安裝truffle $ npm install -g ...
  • 1.計算程式運行時常 2.文件讀寫 3.立flag 設置布爾變數,用來在程式運行時對一些邏輯進行標記。其中false和true需要自己定義其含義。因此在設置flag的時,需要註意false以及true對應的含義。否則這些邏輯上的錯誤很難被檢查出來。 4.使用HashMap 聲明myMap為HashM ...
  • 這個案例類似於在地圖上滾動滾輪,能縮小或者放大地圖,分別用zoomIn和zoomOut來命名。 代碼如下: 另外,detail在滾輪事件中,向上滾——放大(detail == -3),觸發zoomOut;向下滾——縮小(detail == 3),觸發zoomIn。 自定義事件需要trigger來主動 ...
  • 通過資料庫和ajax方法寫出地圖 客戶端部分:html、js、css代碼部分: 服務端部分:app.js(一個JavaScript): 資料庫mysql信息: 最終結果: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...