MVC3 プロジェクトで、jQuery 検証を使用して「利用規約に同意する」チェックボックスを必須にしたいと考えています。現在、「MS データ注釈属性」+「MS MVC3 控えめな jQuery 検証」からサーバー/クライアント DRY/SPOT 検証を取得しています。
ここにスタンドアロン テストがあります (MVC3 によって生成されたプレーン HTML)。なぜ動作しないのでしょうか? 実行すると、検証によって「連絡先名」フィールドが入力されていることが確認されますが、チェックボックスの状態は考慮されません。
<!DOCTYPE html>
<html>
<head>
<title>RequiredCheckbox</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.microsoft.com/ajax/jQuery.Validate/1.7/jQuery.Validate.js"></script>
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js"></script>
<script type="text/javascript" language="javascript">
$(function () {
// http://itmeze.com/2010/12/checkbox-has-to-be-checked-with-unobtrusive-jquery-validation-and-asp-net-mvc-3/
$.validator.unobtrusive.adapters.add("mandatory", function (options) {
options.rules["required"] = true;
if (options.message) {
options.messages["required"] = options.message;
}
}
});
$.validator.unobtrusive.parse(document);
});
</script>
</head>
<body>
<div>
<form>
<input data-val="true" data-val-mandatory="The field Terms Are Accepted is invalid." id="isTermsAccepted" name="isTermsAccepted" type="checkbox" value="true" />
<input name="isTermsAccepted" type="hidden" value="false" />
<span class="field-validation-valid" data-valmsg-for="isTermsAccepted" data-valmsg-replace="true"></span>
<input data-val="true" data-val-required="The Contact Name field is required." id="contactName" name="contactName" type="text" value="" />
<span class="field-validation-valid" data-valmsg-for="contactName" data-valmsg-replace="true"></span>
<button type="submit">Submit</button>
</form>
</div>
</body>
</html>
この投稿の残りの部分は、単なる私の研究メモです。
データ注釈属性 [必須] を設定しても役に立ちません。
http://forums.89.biz/forums/MVC+3+Unobtrusive+validation+does+not+work+with+checkboxes+(jquery+validation)+and+the+fix+for+it。
それは結構です。チェックボックスの「必須」の意味は、明らかに私が踏み込みたくない聖戦です。MS は jQuery チームよりも自分たちの方が詳しいと考えていました。ローカルで強制するのは、次の簡単な作業です。
$("form").validate({ rules: { cbAgreeToTerms: "required" } });
...ですよね?いいえ、理由は次の通りです:
http://blog.waynebrantley.com/2011/01/mvc3-breaks-any-manual-use-of-jquery.html
http://pinoytech.org/question/4824071/microsofts-jquery-validate-unobtrusive-makes-other-validators-skip-validation
何だって?それはかなり安っぽいよ!(もちろん、私の意見だけど。)
今、私はこの解決策を試しました:
http://itmeze.com/2010/12/checkbox-has-to-be-checked-with-unobtrusive-jquery-validation-and-asp-net-mvc-3/
しかし、私には効果がありませんでした。この著者の宙ぶらりんのコメントと、記事の前半にある逆 CHECKBOX テストのややカーゴ カルト的な使用法から、著者にとって本当に効果があるのかどうか疑問に思います。では、他にどんな魔法が関係しているのでしょうか?
注記: JS の最後のスニペットはクリーナーに相当すると思います:
$.validator.unobtrusive.adapters.addBool("brequired", "required");
これは、次の最後の投稿で示唆されました:
http://forums.asp.net/p/1648319/4281140.aspx#4281140
しかし、著者がまだデバッグしていないとコメントしていることに注意してください。私の場合はうまくいきませんでしたが、行間を読むと、著者は自分にはうまくいかなかったという意味だと思います。
unobtrusive.js は docready で parse を呼び出すので、それを呼び出してみましたが、役に立ちませんでした。
$.validator.unobtrusive.parse(document);
また、同様の記事をいくつか見つけましたが、初期化が必要であることについては何も触れられていません。おそらく、それらはすべて、元の/パブリックな unobtrusive.js をローカルで編集しているのでしょうか? できればそうしたくないのですが、アダプターはそのためにあるのではないですか?
ほぼ同じ内容の Stack Overflow の記事と、より複雑な例を見つけました。
ASP .Net MVC 3 控えめなカスタム クライアント検証
カスタム属性のクライアント側検証を実行する
http://xhalent.wordpress.com/2011/01/27/custom-unobstrusive-jquery-validation-in-asp-net-mvc-3/
しかし、私がこれまで試したものと異なる点は何も見当たりません。
これは本当に人々に効果があるのでしょうか? なぜ私には効果がないのでしょうか?
ベストアンサー1
ここに、承認された回答を適用した結果得られた、正しく動作するソース コードをまとめました。お役に立てば幸いです。
必須チェックボックス.aspx
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<RegistrationViewModel>" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>RequiredCheckbox</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
<script src="//ajax.microsoft.com/ajax/jQuery.Validate/1.7/jQuery.Validate.js" type="text/javascript"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
$.validator.unobtrusive.adapters.addBool("mandatory", "required");
</script>
</head>
<body>
<div>
<%
// These directives can occur in web.config instead
Html.EnableUnobtrusiveJavaScript();
Html.EnableClientValidation();
using (Html.BeginForm())
{ %>
<%: Html.CheckBoxFor(model => model.IsTermsAccepted)%>
<%: Html.ValidationMessageFor(model => model.IsTermsAccepted)%>
<%: Html.TextBoxFor(model => model.ContactName)%>
<%: Html.ValidationMessageFor(model => model.ContactName)%>
<button type="submit">Submit</button>
<% } %>
</div>
</body>
</html>
登録ビューモデル.cs
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public class RegistrationViewModel {
[Mandatory (ErrorMessage="You must agree to the Terms to register.")]
[DisplayName("Terms Accepted")]
public bool isTermsAccepted { get; set; }
[Required]
[DisplayName("Contact Name")]
public string contactName { get; set; }
}
必須属性.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public class MandatoryAttribute : ValidationAttribute, IClientValidatable
{
public override bool IsValid(object value)
{
return (!(value is bool) || (bool)value);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationType = "mandatory";
yield return rule;
}
}