MVC Web アプリに jQuery Unobtrusive Validation を使用するためのかなりの防弾セットアップができたと思っていましたが、最近のバグで非常に困惑しています。
すべての検証を一貫したものにしたいので、リモート検証属性とコントローラー メソッドを使用して、固有の電子メール/ユーザー名のチェックなどをカバーします。私はかなり早い段階で、サーバー側で呼び出しに誤検知が発生するのにあまり時間がかからないことをform.valid()
発見したので、保留中の検証チェックと検証が完了するまで待機する間隔をハッキングしてから、最終的にエラー メッセージを出力するか、フォームを送信しました。 .
以下のコードは、onclick 関数をバインドし、フォームの onkeyup 検証をオフにします。
$(document).ready(function () {
// Bind events to buttons so they can be removed later
$('#btnSave').click(function () {
SaveEntry();
});
$('#btnCancel').click(function () {
$('#dialog-Timesheet').dialog('close');
});
var $form = $("#btnSave").closest("form");
// Just something I was trying..
$.validator.unobtrusive.parse($form);
// Find the validator and turn temporarily turn of onkeyup validation to prevent user making the form valid before the remote validation is complete
var validator = $form.data("validator");
// Seems to work with the below on its own but keyup still fires validation later
validator.settings.onkeyup = false;
});
SaveEntry()
次に、フォームを見つけてそのバリデーターを見つけ、インターバルを使用して、フォームを最終的にチェックしてエラーメッセージを出力するか、ajax リクエストを送信する前に、保留中の検証リクエストがあるかどうかを確認する、以前にバインドされたメソッドがあります。
function SaveEntry() {
var $form = $("#btnSave").closest("form");
var validator = $form.data("validator");
var closeButton = "<br/><input type='button' value='OK' style='font-size:small; font-weight:bold; float:right;' onclick=\"$('#dialog-Timesheet').dialog('close');\" class='greenbutton' />";
var errorMessage = "";
var successMessage = "";
// Starts the remote validation checks
if ($form.valid()) {
}
// Call function every 30 milliseconds
interval = setInterval(pendingValidationComplete, 30);
// Saves or validates as long as no validation pending
function pendingValidationComplete() {
// This only runs once remote validation is finished
if (validator.pendingRequest === 0) {
clearInterval(interval);
//Force validation to present to user (this will not retrigger remote validation)
if ($form.valid()) {
// If is valid then submit
if ($('#TimeSheetEntryID').val() > 0) {
$.ajax(
{
type: "POST",
url: "/Timesheet/EditEntry",
data: "id=" + $('#Id').val() + "&" + $form.serialize(),
success: function (result) {
ShowData("fromCookie", "current");
successMessage = "<div style='text-align:center; margin-top: 10px;'>" + result + "<div>";
$openDialog.html(successMessage + closeButton);
},
error: function (jqXhr, textStatus, errorThrown) {
// Populate dialog with error message and button
errorMessage = "<div style='text-align:center'>Error '" + jqXhr.status + "' (Status: '" + textStatus + "', errorThrown: '" + errorThrown + "')<div>";
$openDialog.html(errorMessage + closeButton);
}
});
} else {
$.ajax(
{
type: "POST",
url: "/Timesheet/CreateEntry",
data: $form.serialize(),
success: function (result) {
ShowData("fromCookie", "current");
successMessage = "<div style='text-align:center; margin-top: 10px;'>" + result + "<div>";
$openDialog.html(successMessage + closeButton);
},
error: function (jqXhr, textStatus, errorThrown) {
// Populate dialog with error message and button
errorMessage = "<div style='text-align:center'>Error '" + jqXhr.status + "' (Status: '" + textStatus + "', errorThrown: '" + errorThrown + "')<div>";
$openDialog.html(errorMessage + closeButton);
}
});
}
}
//else { alert("invalid"); }
}
//else { alert("NOT YET"); }
};
}
したがって、これはすべてうまく機能しますが、別の問題のテスト中に、フォームを送信すると、必要なフィールドが期待どおりに無効になることがわかりましたが、必要なフィールドを十分に迅速に修正すると (おそらくループしている間)元のエラー メッセージが表示されてからクリックしていなくても、リクエストは送信されます。したがって、onkeyup はバリデーター (およびその保留中の検証値) または何かをリセットする必要があると思います。そのため、間隔内の次のチェックは有効であり、送信されますか? しかし、確認のために調べたドキュメントやさまざまな投稿には何も見つかりません。
一時的な回避策として、フォームの onkeyup を停止することを考えましたが、同じシナリオで、無効なフィールドに有効なデータをすばやく入力すると、onkeyup が起動し、フォームが送信されます。これは関連していると思いますが、バリデーターの設定が常に表示onkeyup = false
されるため、検証して送信する理由がわかりません。
どんなアイデアでも大歓迎です。フォームは、パーシャルを返すコントローラー メソッドへの ajax 要求の後、jQuery ダイアログに表示されます。htmlには特別なことは何もありません。
より明確にすることができるか、何かを追加できるかどうか教えてください。