web-dev-qa-db-ja.com

クライアント側のフォームの検証と対話に最適なJavaScriptソリューションですか?

Webフォームは本当に複雑です。拡張可能なフォーム検証のための優れたソリューションは何ですか、できればjQueryで動作するものですか?

背景:

私たちのサイトには少しAjaxがありますが、本当の焦点は約20のマルチページフォームまたは「ウィザード」によるユーザーエクスペリエンスです。これらのフォームは複雑です。

  • Presentation:一部のフィールドはfloatまたはintです。検証とは、10進数以外の文字を削除することを意味しますが、ユーザーが5を価格フィールドに入力すると、フィールドは5.00
  • 副作用:一部のフィールドは更新時に副作用があります。たとえば、アイテムの価格または数量を更新するには、小計フィールドを更新する必要があります。
  • ウィジェット駆動型要素:一部のフィールドは非表示で、ウィジェットによって値が入力されます。たとえば、マップウィジェットを使用すると場所をポイントでき、非表示フィールドは緯度経度座標で更新されますが、場所は特定の地域内にある必要があります。
  • グループ:一部のフィールドはアドレス/都市/州/ Zipなどのグループであり、すべてのフィールドにデータが入力された場合にのみ検証する必要があります。
  • サーバー側の検証:一部のフィールドの検証には、Ajaxリクエストによるバックエンドのチェックが必要です
  • ページごとの複数のフォーム:ユーザーがダイアログを別のフォームで開く前に、あるフォームに記入する必要がある場合があります。フレームワークは、onSubmitにバインドするよりも汎用性が高い必要があります。Ajaxを使用して、同じページから複数のフォームを順番に投稿することがあります。 (たとえば、ユーザーがサインアップして1回でウィジェットを作成できるようにしますが、レガシーシステムのために、そのフローには2つのPOSTリクエストが必要です。)
  • カスタマイズ可能なエラー表示:フィールド上にエラーが表示される場合があり、フィールドスタイルが変更される場合があり、新しいデザインではツールチップのようなポップアップが必要です(ala qTip )いくつかのエラー。
  • Snappiness:ユーザーエクスペリエンスが重要であり、触覚フィードバックが重要です。あらゆる解決策
  • 送信ボタン:送信ボタンをクリックすると、すべてを検証してから応答を表示する必要がありますが、検証の一部は非同期に発生するためです。

現在、 jQuery Validation ライブラリを使用していますが、フォームはその機能を超えているようです。私は <angular />Knockout 、および Backbone.js のようなものを見てきましたが、それらがあまりにも心配ですヘビー級またはフロントエンドを書き換える必要があります。

(これはコミュニティwikiである必要があります。)

52
a paid nerd

これは恥知らずなプラグですが、私が設計した framework をボランティアしてもいいですか?注釈(Hibernate Validatorに似ています)に基づいて構築しました。カスタム制約をサポートしており、非常に強力だと感じています。 ここ はStackoverflowの質問でもあり、フレームワークのレビューをお願いしました。

  • Presentation:カスタムのvalidation-constraintsを使用すると、onChange要素に検証をバインドできます。また、Regulaはカスタムバリデータをサポートしているため、カスタムバリデータにフィールドの値を更新させることができます(したがって、5から5.00)。
  • 副作用:レギュラは、カスタム制約バリデーターによる副作用をサポートします。
  • Groups:Regulaは検証グループをサポートしています。特定のグループを検証の対象にすることができます。カスタムバリデーターとグループを組み合わせることで、そのグループのすべての要素が満たされたときにonlyを検証するようにバリデーターの動作を制御できます(このチェックを実行する必要があります)通常のJavascriptを介して)。
  • サーバー側検証:カスタム制約を使用すると、AJAX呼び出しを行ってサーバー側検証を実行できます。現在のフレームワークの構造では、これは必然的にブロックするajax呼び出しである必要がありますが、今後は非同期機能を追加する予定です。
  • ページごとに複数のフォーム:レギュラは、ページごとに1つのフォームを検証することに制限されません。複数のフォームを処理できます(要件を正しく理解しているかどうかはわかりません。そのため、この部分に正しく回答できなかった可能性があります)。
  • カスタマイズ可能なエラー表示:検証に関する限り、RegulaはページのUIに対して何もしません。検証すると、エラーメッセージなどを含む一連の制約違反が発生します。それらの表示方法はあなた次第です。
  • Snappiness:ベンチマークを実行していないため、この点でフレームワークのパフォーマンスについてコメントすることはできません。
  • 送信ボタン:これはまだ解決していません(非同期と同期)。

以下に例を示します。

以下に、組み込みの制約を使用した標準検証を示します。

<input id = "myInput"
       name = "myInput"
       type = "text"
       class = "regula-validation"
       data-constraints = '@NotEmpty @IsNumeric @Between(min=1, max=5)' />

jQuery(document).ready(function() {
    // must call regula.binnd() first. The best place would be in an
    // onload handler. This function looks for elements with
    // a class name of "regula-validation" and binds the
    // appropriate constraints to the elements

    regula.bind(); 

    jQuery("#myForm").submit(function() {
        // this function performs the actual validation
        var validationResults = regula.validate();

        for(var index in validationResults) {
             var validationResult = validationResults[index];
             alert(validationResult.message);
        }
    });
});

ご覧のとおり、制約違反のみを処理しているため、エラーメッセージを表示する方法は完全にユーザー次第です。

カスタム制約の例を次に示します。

regula.custom({
   name: "MustBe42",
   defaultMessage: "The answer must be equal to 42",
   validator: function() {
      return this.value == 42;
   }
});

そしてその使用:

<input id = "theAnswerToLifeTheUniverseAndEverything" 
       name = "theAnswerToLifeTheUniverseAndEverything" 
       value = ""
       class = "regula-validation"
       data-constraints = "@MustBe42" />

バリデータはJavascript関数であるため、何でも実行できます(これにより、副作用に関する質問に対処します)。

パラメーターを受け入れる別の制約の例を次に示します。

regula.custom({
   name: "DivisibleBy",
   defaultMessage: "{label} must be divisible by {divisor}",
   params: ["divisor"],
   validator: function(params) {
      var divisor = params["divisor"];
      return (this.value % divisor) == 0;
   }
});

そして使用法:

<input id = "number" 
       name = "number" 
       value = ""
       class = "regula-validation"
       data-constraints = "@DivisibleBy(divisor=3, label='The Number')" />

検証グループの使用例を次に示します。

<input id = "score"
       name = "score"
       type = "text"
       class = "regula-validation"
       data-constraints = '@IsNumeric(label="Score", 
                                      message="{label} needs to be a number!"
                                      groups=[FirstGroup, SecondGroup, ThirdGroup]' />

<input id = "age"
       name = "age"
       type = "text"
       class = "regula-validation"
       data-constraints = '@IsNumeric(label="Age", 
                                      message="{label} needs to be a number!"
                                      groups=[SecondGroup]' />

<input id = "name"
       name = "name"
       type = "text"
       class = "regula-validation"
       data-constraints = '@NotEmpty(label="Name", 
                                     message="{label} cannot be empty!"
                                     groups=[FirstGroup]' />

そして、FirstGroupのみを検証するスニペット(したがって、scorenameのみが検証されます):

var constraintViolations = regula.validate({groups: [regula.Group.FirstGroup]});
var messages = "";

for(var index in constraintViolations) {
      var constraintViolation = constraintViolations[index];
      messages += constraintViolation.message + "\n";
}

if(messages != "") {
   alert(messages);
}

試してみる予定がある場合は、バージョン1.1.1をダウンロードすることをお勧めします。現在のドキュメントは、そのバージョンに特に一致しています。 1.2.1では、複合制約のサポートを追加しましたが、それを反映するようにドキュメントを更新していません。

これですべての懸念に対処できない場合、またはこれがあなたが探しているものではない場合、私は理解しています。私はそれをそこに置くだけだと思った。また、あなたがそれをチェックアウトした場合、バージョンを反映するようにドキュメントを更新することを確認します1.2.1。私は学校と仕事で忙しかったので、それをする時間がありませんでした。

更新#1

Sohnee はクライアント側の検証に言及しています。私は実際にRegulaとSpring 3の統合に取り組んでいます。願わくば、近いうちに(また、仕事と学校に依存して)それをリリースできることを願っています。統合は、Hibernate検証制約をRegula検証制約に変換することにより機能します。この方法では、検証コードを1回(ほとんど)書くだけで済みます。ただし、カスタム制約の場合、Javascript側(カスタムバリデーター)でコードを記述する必要があります。ただし、Hibernateの検証制約を使用してサーバー側のコードに注釈を付けたら、クライアント側で何もする必要はありません。これらの制約は、クライアント側のフォーム要素に自動的に適用されます。

Matthew Abbott は、 RegulaをASP.NET MVCと統合する も可能になりました。

更新#2

Hibernate Validatorを使用したRegulaとSpring 3.0.x Web MVCの統合を示すデモwebapp(mavenized) github があります。それは実際に文書化されたものでも何でもありません。概念実証です。統合とその仕組みに関するドキュメントをgithubページに追加する予定です。

更新#3

wiki のドキュメントを更新し、最新バージョンに対応するようになりました1.2.2(私は作りました少しのバグ修正。これが1.2.2の理由です)。

55
Vivin Paliath

私はこれを jQuery formValidator をさまざまな環境全体と組み合わせて数回使用しました。設定に1時間以上かかることはめったにないので、これが役立つことを願っています。

乾杯!

13
Mitch Malone

jQuery Validation プラグインは良い仕事をしていると思います。 metadata プラグインと組み合わせて、サーバー側の検証パラメーターをクライアントに渡します。また、検証に共通のパターンを使用できるようにすべてのフォームにいくつかのキーポイントをラップし、いくつかの例外/カスタム状態を使用しました。これには、カスタムアラートメッセージと表示が含まれます。

箱から出してすぐに望むすべてを行うわけではありませんが、これは私が見た中で最良のオプションであり、デフォルトの動作です。繰り返しますが、メタデータ(属性 "data-meta")を使用します。そして、それはあなたの意志に曲げることができます。また、クライアント側の入力要素へのコントロールバインディングにメタデータを使用しています。これにより、クライアント側のロジックがサーバー側から分割されますが、長い目で見ればサーバー側のロジックからjsを注入しようとする方が簡単です。

8
Tracker1

Parsley.js は、執筆時点(2013年8月)でニースで人気のある選択肢のようです。

5
Simone

チームの誰かがjQuery Toolsのバリデーターに気付いたので、自分でこれに答えます!

  • プレゼンテーション-HTML5入力フィールドをサポートします。 patternフィールドは、ユーザーが特定のパターンでのみテストを入力できるようにします。
  • 副作用-フォームおよび個々のフィールドでイベントをトリガーします:onFailおよびonSuccess
  • ウィジェット駆動型要素-「カスタム入力タイプ」が推奨されます。基本的なデモには、自然数の古い「年齢」フィールドも含まれています。
  • Groups-検証するフィールドをフィルタリングすることを唯一の目的とする「関数マッチャー」を作成します。
  • サーバー側の検証-それを実行し、インテリジェントに実行します-戻り値の代わりにコールバックを呼び出す検証者に依存します(したがって、非同期フレンドリーです)。
  • ページごとに複数のフォーム-jQuery Toolsは非常にうまく構築されているようで、これは問題ではないはずです。
  • カスタマイズ可能なエラー表示-フィールドの横のエラー?一箇所にすべて?問題ない。まだ十分ではありませんか?失敗時にイベントをバインドします。デフォルトでもツールチップを使用します。
  • Snappiness-デモは非常に機敏です
  • 送信ボタン-問題ありません。

更新:はい、jQuery Toolsのバリデータツールチップでサイトのチャンクを再実装しました。素晴らしい!

2
a paid nerd

サーバー側の検証は揺れ動きます。

必要に応じてAJAXリクエストを介してこのような検証の結果を提供するか、クライアント側の検証も追加するサーバー側フレームワークを使用します。ただし、2回記述しないでください。

1
Fenton
 function isEmpty(text) {
if(text == undefined) {
    return true;
}
if(text.replace(/\s+/g, ' ').length == 0) {
    return true;
}
return false;
}

function isValidBoolean(text) {
   if(text == undefined || (text.toLowerCase() != "true" &&    text.toLowerCase() != "false")) {
    return false;
}
return true;
 }

  function isValidDouble(text) {
     var out = parseFloat(text);
   if(isNaN(out)) {
    return false;
  }
  return true;
  }

  function isValidLong(text) {
var out = parseInt(text);
if(isNaN(out)) {
    return false;
}
return true;
}

 function isValidDate(text) {
if(Date.parseString(text, 'MM/dd/yyyy HH:mm:ss') == null) {
    return false;
}
return true;
}

  function hasDuplicates(array) {
var valuesSoFar = {};
for (var i = 0; i < array.length; ++i) {
    var value = array[i];
    if (Object.prototype.hasOwnProperty.call(valuesSoFar, value)) {
        return true;
    }
    valuesSoFar[value] = true;
}
return false;
}
0
Sushant Patil

JQuery Validationプラグインを使用してください。今まで失敗したことはない

0
Hello Universe