電話番号と米国の郵便番号フィールドに jQuery Validate と Masked Input の両方を使用しているフォームがあります。
たとえば、米国の郵便番号の場合、マスク入力では数字のみを入力でき、「99999」または「99999-9999」の形式を強制します(9は任意の数字です)。検証ルールも同じです。ただし、場合によっては、Validateは実際に有効であるはずのフィールドを無効としてマークします。
JQuery Validateが郵便番号フィールドで使用している正規表現は_^\d{5}$|^\d{5}\-\d{4}$
_です。
マスク入力で適用するマスクは.mask('99999?-9999')
です
次のようにすると、それらの間の競合が発生します。
9桁のZipを入力しても、この問題は起こりません。
このエラーは、5桁のZipの場合、マスクされた入力が一時的に「-____」を挿入して、オプションでダッシュと4桁以上を入力できることをユーザーに示すためだと思います。これはぼかしで削除されますが、アンダースコアが許可されていないため、削除される前にフィールドが検証されて失敗します。
この仮説は、フォームが後で再検証される場合、Zipフィールドが合格するという事実によってサポートされます。私はこれを2つの方法で行いました。
特定のフィールドを再検証する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
_バージョンを実行する必要があります。
私は実際にこの正確な質問に対する答えを探していました。より信頼できる回避策を考え出すことになりました。
郵便番号に対して独自のバリデーターメソッドを定義しているため、値からプレースホルダーを削除した後、郵便番号の長さが6の場合にハイフンが削除されるように変更しました。
それはこのように見えました:
$.validator.addMethod("zipcode", function(postalcode, element) {
//removes placeholder from string
postalcode = postalcode.split("_").join("");
//Checks the length of the zipcode now that placeholder characters are removed.
if (postalcode.length === 6) {
//Removes hyphen
postalcode = postalcode.replace("-", "");
}
//validates postalcode.
return this.optional(element) || postalcode.match(/^\d{5}$|^\d{5}\-\d{4}$/);
}, "Please specify a valid Zip code");
したがって、検証している郵便番号は、入力プラグインによってプレースホルダーが追加され、入力された郵便番号が5桁の数字(ハイフンを含めて6桁)のみの場合、ハイフンが削除されます。したがって、適切に検証されます。
私は次の解決策を試してみましたが、それは魅力のように機能します。
_$("[data-input-type=phone]", "body")
.mask("(999) 999 99 99")
.bind("blur", function () {
// force revalidate on blur.
var frm = $(this).parents("form");
// if form has a validator
if ($.data( frm[0], 'validator' )) {
var validator = $(this).parents("form").validate();
validator.settings.onfocusout.apply(validator, [this]);
}
});
_
問題の原因はイベントの順序付けです。要素がマスクされると、blur
のmaskedinputプラグインによって検証されますが、同じ要素はfocusout
イベントのバリデータープラグインによって検証されます(非IEブラウザーのブラーのラッパーです)。 maskedinputのブラーの前に呼び出されます。
この状況では、バリデーターが値をチェックするとき、input要素の値は"(___) ___ __ __"
です。コードがmaskedinputのblurイベントに到達すると、プラグインは有効な入力ではないため、値をテストしてクリアします。
検証結果は、検証ケースごとに異なる場合があります。たとえば、required
ルールは、要素に値があるため、成功します。 _"999"
_のようなマスクは_12_
_としてテストされる可能性があるため、入力を空のままにしても必須ではないnumber
フィールドは失敗します
上記のコードは、マスクされた入力のフォームに検証が関連付けられているかどうかをテストし、focusoutイベントハンドラーを呼び出します。私たちのハンドラーは最新のものとして添付されているので、うまくいけばそれが最後に呼び出されるでしょう。
警告、コードは単に検証プラグインの動作をコピーします。おそらく10年間は機能しますが、検証プラグインが現在とは異なることを行うと決定した場合は失敗する可能性があります。
心から
単にmask()関数にフックし、追加のロジックを追加して、デフォルトのマスクのぼかしロジックの後に独自のぼかしロジックを起動します。
//Store the original mask function
var origMaskFn = $.fn.mask;
$.fn.mask = function (mask, settings) {
//Call the original function applying the default settings
origMaskFn.apply(this, [mask, settings]);
//Manually validate our element on blur to prevent unobtrusive messages
//from showing before the mask is properly scrubbed
$(this).bind('blur', function () {
var $form = $(this).parents('form');
if (!$form.exists())
return;
var validator = $form.validate().element($(this));
});
}
また、 'exists()'関数に気づくかもしれません。これは、jQueryセレクターでよく使用するものです。
//Function to detect if a jQuery elements exists. i.e.:
// var $element = $(selector);
// if($element.exists()) do something...
$.fn.exists = function () {
return this.length !== 0;
}
同様の問題があり、デフォルトのプレースホルダー文字を空の文字列に変更することで解決できました。
私は.mask('9?99');
を使用していて、単純な「数値」ルールで検証しており、同じ種類の競合が発生していました。
マスク宣言を.mask('9?99',{placeholder:''});
に変更しました...これ以上競合しません。 :)
マスクプラグインによってフォームに常に挿入される郵便番号の-
が原因で、問題が発生する可能性があります。私はあなたが正規表現を^\d{5}\-$|^\d{5}\-\d{4}$
に変更できると思います(どちらの場合もダッシュに一致します)。
とにかく、あなたはしばらく前に投稿し、おそらくこれはもう必要ありませんが、おそらく他の人を助けるでしょう。 :)
バインディングを行う順序は重要ですか?たとえば、間に違いはありますか
$(function() {
var $form = $("#myForm"), $Zip = $("#Zip");
$Zip.mask("99999?-9999");
$form.validate();
});
そして
$(function() {
var $form = $("#myForm"), $Zip = $("#Zip");
$form.validate();
$Zip.mask("99999?-9999");
});
ビンディングは順番に発砲するべきだと思います。
私はいくつかの解決策を試しましたが、どれもうまくいきませんでした。私は「bootstrapValidator」( http://bootstrapvalidator.com/ )と「jquery.maskedinput」( http:/ /digitalbush.com/projects/masked-input-plugin/ )なので、誰かがまだこの問題を抱えている場合、私の解決策は:
私の入力は次のようにマークされました:
<input type="text" class="form-control" id="telefone" placeholder="(__) ____-_____" name="telefone" required>
そして、このような完全なスクリプト:
$(document).ready(function() {
var telefone = $('#telefone'), //THAT'S MY INPUT WITH MASK
form = telefone.parents("form"), //THAT'S MY FORM WITH THE VALIDATE
alteredField = false; //THAT'S A FLAG TO SSE IF THE INPUT WAS ALTERED
// APPLY MY MASK
telefone.mask('(99) 9999-9999?9');
// FOCUS ON ANY INPUT
form.find('input[type=text]').focus(function(){
// REMOVE THE VALIDATION STATUS
$(form).data('bootstrapValidator').updateStatus($(this).attr('name'), 'NOT_VALIDATED');
// ENABLE THE SUBMIT BUTTON
$(form).data('bootstrapValidator').disableSubmitButtons(false);
});
// FOCUS ON THE MASKED INPUT
telefone.focus(function(){
// DISABLE THE VALIDATE
$(form).data('bootstrapValidator').enableFieldValidators('telefone', false);
// ENABLE THE SUBMIT BUTTON
$(form).data('bootstrapValidator').disableSubmitButtons(false);
}).blur(function(){ // BLUR ON THE MASKED INPUT
// GET THE INPUT VALUE
var value = telefone.val();
// ENABLE THE VALIDATE
$(form).data('bootstrapValidator').enableFieldValidators('telefone', true);
// CHECK IF THE VALUE IS EMPTY
if(value != ""){
// CHANGE THE STATUS OF THE INPUT TO VALID
$(form).data('bootstrapValidator').updateStatus('telefone', 'VALID')
// ACTIVE THE FLAG
alteredField = true;
}else if (alteredField) { // IF THE INPUT WAS ALTERED BEFORE AND DON'T HAVE VALUE
// CHANGE THE STATUS OF THE INPUT TO INVALID
$(form).data('bootstrapValidator').updateStatus('telefone', 'INVALID')
};
});
});
このコードは「bootstrapValidator」の標準的な動作を変更しますが、私がバグを解決するために得た唯一の方法でした。
パフォーマンスの問題についてはわかりません。コードを変更して改善してください^^この情報がお役に立てば幸いです^ _ ^
私は同じ問題に直面し、適切な解決策をとるために2時間を費やしました。最後に、適切なコードを作成しました。使えます
郵便番号の場合。
$.validator.addMethod("zipcode", function(postalcode, element) {
//removes placeholder from string
postalcode = postalcode.replace(/[^0-9]/g, "");
//validates postalcode.
return this.optional(element) || postalcode.match(/^\d{5}$|^\d{5}\-\d{4}$/);
}, "Please specify a valid Zip code");
Zipの長さを増減する場合は、postalcode.match(/ ^\d {5} $ | ^\d {5}-\ d {4} $ /);を変更します。あなたの要件に応じて番号。
電話の場合は同じコードが使用されますが、postalcode.match(/ ^\d {10} $ | ^\d {10}-\ d {9} $ /);のような番号のみを変更する必要があります。
$.validator.addMethod("phone_length", function(phoneno, element) {
//removes all special characters
phoneno= phoneno.replace(/[^0-9]/g, "");
return this.optional(element) || phoneno.match(/^\d{10}$|^\d{10}\-\d{9}$/);
}, "Please enter a valid phone");
このコードがあなたのお役に立てば幸いです。呼び出し方法を知りたい場合は、検証フィールドにzipcode:trueを追加するだけです