電話番号と米国の郵便番号フィールドにjQuery ValidateとMasked Inputの両方を使用するフォームがあります。
たとえば、米国の郵便番号の場合、Masked Input は数字のみの入力を許可し、"99999" または "99999-9999" (9 は任意の数字) のいずれかの形式を強制します。Validate ルールでも同じことが必要です。しかし、実際には有効であるべきフィールドが Validate によって無効としてマークされる場合があります。
コード仕様
jQuery Validate が郵便番号フィールドで使用している正規表現は^\d{5}$|^\d{5}\-\d{4}$
.
Masked Input で適用しているマスクは.mask('99999?-9999')
再現する手順
次の操作を行うと、それらの間の競合が発生します。
- 無効な郵便番号 (3 桁など) を入力してください
- タブでフィールドから離れます。マスクされた入力は入力を消去し (予期される動作)、jQuery Validate は空白であるため無効としてマークします (これも予期されます)。
- 郵便番号フィールドに戻り、有効な5 桁の郵便番号を入力します。
- タブでフィールドから離れます。まだ無効としてマークされています。これは予想外です。
9 桁の郵便番号を入力すると、この問題は発生しません。
仮説
このエラーは、5 桁の zip の場合、Masked Input が一時的に "-____" を挿入して、オプションでダッシュとさらに 4 桁を入力できることをユーザーに示すためだと思います。これはぼかしで削除されますが、アンダースコアが許可されていないため、削除される前にフィールドが検証されて失敗します。
この仮説は、フォームが後で再検証された場合に zip フィールドがパスするという事実によって裏付けられています。私はこれを2つの方法で行いました:
フォームを送信することにより; 送信ボタンがクリックされ、zip フィールドが通過し、フォームが送信されると、すべてのフィールドが再検証されます。
blur
その特定のフィールドを再検証するイベントを設定する。例えば:$("#zipcode").blur(function(){ $(this).closest('form').validate().element($(this)); });
これはハッキーな解決策として役立ちますが、満足できるものではありません。なぜなら、1) デフォルト設定はすでにぼかし時に再検証されているため、これが繰り返され、2) 通常の Validate ルール以外に追加のコードが必要になるためです。
他の誰かがこの問題に遭遇しましたか? 追加のぼかしイベント リスナーを設定するよりも洗練されたソリューションはありますか?
更新: ハッキング ソリューションの適用
上記のハッキーなソリューションを適用しても、思ったほどうまくいきません。たとえば、これは機能しません:
$appDiv.delegate('input,select,textarea','blur',function(){
$(this).closest('form').validate().element($(this));
});
...これもしません:
$('input,select,textarea').live('blur',function(){
$(this).closest('form').validate().element($(this));
});
...しかし、これは:
$('input,select,textarea').each(function(){
$(this).blur(function(){
$(this).closest('form').validate().element($(this));
});
});
これらの要素は AJAX によって読み込まれる.each
ため、フォーム セクションが読み込まれるたびにバージョンを実行する必要があります。