English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

jquery.validate[.unobtrusive]とBootstrapでtooltipエラーポップアップ問題の分析

似たような記事が既にあります。こちらを参照してください。個人的には少し複雑に感じており、最近簡単なプロジェクト用のものを書くことを考えていました。以下に記録しました。最終的な効果は以下の通りです:

バックエンドはAsp.net mvcを使用しています5、フロントエンドフレームワークには: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が追加されます-の属性が先頭に来る-valはこのコントロールが検証が必要であることを示し、他のdata-開始部分は一連の検証ルールとエラーメッセージが含まれており、エラーメッセージはカスタマイズ可能です。そうでない場合、フレームワークは「字段 EnterpriseNo は最大長さが」のようなテンプレートを自動生成します。30の文字列または配列の型です。もちろん、これらの属性はjquery.validateは認識しません。jquery.validateが認識するようにするには、jquery.validate.unobtrusiveが介入する必要があります。

これらのjsはどのように連携して使用されるかについて説明します。

新版本的jquery.validateはAMDモードをサポートしており、直接requirejsで読み込むことができますが、jquery.validate.unobtrusiveはshim設定が必要で、以下のようになります:


      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の核心コードです:

define(['validateunobtrusive'], function () {}}
  function TooltipValidator() {}
  TooltipValidator.prototype = {
    init: function (validatorOptions, tooltipOptions) {
      tooltipOptions = tooltipOptions || {};
      validatorOptions = validatorOptions || {};
      this._tooltipOptions = $.extend({}, {
        placement: 'top'
      }, tooltipOptions, { animation: false });
      this._validatorOptions = $.extend({}, {
        //errorPlacement: function (error, element) {
        //  // do nothing
        //},
        showErrors: function (errorMap, errorList) {
          for (var i = 0; i < this.successList.length; i++) {}}
            var success = this.successList[i];
            $(this.successList[i]).tooltip('destroy');
            $(this.successList[i]).parents('div.form-group').removeClass('has-error');
          }
          for (var i = 0; i < errorList.length; i++) {}}
            var errorElement = $(errorList[i].element);
            errorElement.parents('div.form-group').addClass('has-error');
            errorElement.attr('data-original-title', errorList[i].message).tooltip('show');
          }
        },
        submitHandler: function (form) {
          return false;
        }
      }, validatorOptions)
      this._configTooltip();
      this._configValidator();
    },
    _configTooltip: function () {
      $('[data-val="true"]').tooltip(this._tooltipOptions);
    },
    _configValidator: function () {
      $.validator.setDefaults(this._validatorOptions);
      $.validator.unobtrusive.parse(document);
    }
  }
  return new TooltipValidator();
});

このようにして、requireコールバック関数内でtooltipvalidator.initを実行することができ、別のロジックを書く必要がなくなります。結果として、フロントエンドの同僚も喜んでいます。ここに一つ注意点があります。皆さんは第49行コード、これはjquery.validate.unobtrusiveを初期化する手順です。元々、jquery.validate.unobtrusiveのコードには$(function () { $jQval.unobtrusive.parse(document); });という部分がありましたが、$.readyはDOM要素が読み込まれた後に(話外れですが:レンダリングが完了した後に)実行されるため、tooltipvalidatorの_configValidatorが実行される前に完了してしまい、私たちの設定オプションが無効になります(シングルページ無刷新アプリケーションでは、再びローカルページをロードすると設定オプションが有効になることがあります。なぜなら、$.readyは初回ロード時にのみ実行され、requireコールバックはロードごとに実行されるからです)。解決策は2つあります:1、让jquery.validate.unobtrusive依赖tooltipvalidator;2、移除jquery.validate.unobtrusive中的$jQval.unobtrusive.parse(document);这里选择第2種。

ご読阅ありがとうございました。皆様に役立つことを願っています。皆様の本サイトへのサポートに感謝します!

声明:本文の内容はインターネットから提供され、著作権者に帰属します。インターネットユーザーにより自発的に貢献し、アップロードされた内容であり、本サイトは所有権を有しないです。また、人間による編集は行われていません。著作権に関する問題があれば、メールで:notice#wにご連絡ください。3codebox.com(メールを送信する際、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認がつき、本サイトは侵害された内容をすぐに削除します。)

おすすめ