MVC3: сделать флажок обязательным с помощью jQuery validate? - PullRequest
44 голосов
/ 08 февраля 2011

Я хочу, чтобы мой флажок «Принять условия» был обязательным при использовании jQuery validate в проекте MVC3. В настоящее время я получаю подтверждение DRY / SPOT сервера / клиента из раздела «Атрибуты аннотации данных MS» + «Ненавязчивая проверка MSQC jQuery».

Вот автономный тест (простой HTML, сгенерированный MVC3). Почему это не работает, пожалуйста? При запуске проверка обеспечивает заполнение поля «Имя контакта», но не заботится о состоянии флажка.

<!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 вызывает parse для docready, поэтому я попытался вызвать его, но мне это не помогло.
$.validator.unobtrusive.parse(document); Я также нашел несколько похожих статей, и ни одна из них не говорит о необходимости какой-либо инициализации. Может, они все локально редактируют оригинальный / публичный unobtrusive.js? Я бы предпочел не делать этого, если бы не адаптеры?

Я нашел статьи с переполнением стека, почти такие же, как и более сложные примеры:
Ненавязчивая пользовательская проверка ASP .Net MVC 3
Выполнить проверку на стороне клиента для пользовательского атрибута
http://xhalent.wordpress.com/2011/01/27/custom-unobstrusive-jquery-validation-in-asp-net-mvc-3/
Но я не вижу там ничего такого, что я уже пробовал.

Это действительно работает для людей? Почему я не могу заставить его работать на меня?

Ответы [ 3 ]

60 голосов
/ 22 марта 2011

Я суммировал здесь правильно работающий исходный код, полученный в результате применения принятого ответа.Надеюсь, вы найдете это полезным.

RequiredCheckbox.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>

RegistrationViewModel.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; }
}

MandatoryAttribute.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;
    }
}
32 голосов
/ 08 февраля 2011

Просто измените свой 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;
        }                
    });            
} (jQuery));

Вам на самом деле не нужно писать свой собственный адаптер, и вы можете просто использовать:

(function ($) {
    $.validator.unobtrusive.adapters.addBool("mandatory", "required");
} (jQuery));
0 голосов
/ 18 февраля 2011
<asp:Content ID="Content1" ContentPlaceHolderID="MainContentPlaceHolder" runat="server">
    <h2>
        Save New Contact</h2>
    <%using (Html.BeginForm("SaveContact", "Contact", FormMethod.Post, new { id = "UserImportTypeForm", @autocomplete = "off" })) %>
    <%{ %>
    <table style="height: 100px;">
        <tr>
            <td>
                Import Type :
            </td>

        </tr>
        <tr>
            <td>
                Is Verified
            </td>
            <td>
                <%-- <%=Html.TextBox("UserContactModel.IsVerified", new SelectList(Model.IsVerified, "IsVerified"), new { })%>>--%>
                <%-- <input type="text" name="txtIsVerified" id="txtIsVerified" />--%>
                <%-- <%= Html.TextBox("txtIsVerified")%>--%>
                <%=Html.CheckBox("SelectedUserContact.IsVerified", Convert.ToBoolean(Model.SelectedUserContact.IsVerified) )%>
                <%=Html.ValidationSummary("txtIsVerified", "*")%>
            </td>
        </tr>
        <tr>
            <td>
                First Name
            </td>
            <td>
                <%--<input type="text" name="txtFirstName" id="txtFirstName" />--%>
                <%=Html.TextBox ("SelectedUserContact.FirstName", Model.SelectedUserContact.FirstName )%>
                <%-- <%=Html.ValidationSummary("FirstName", "*")%>--%>
            </td>
        </tr>
        <tr>
            <td>
                Last Name
            </td>
            <td>
                <%--<input type="text" name="txtLastName" id="txtLastName" />--%>
                <%=Html.TextBox("SelectedUserContact.LastName", Model.SelectedUserContact.LastName)%>
                <%=Html.ValidationSummary("LastName", "*")%>
            </td>
        </tr>
        <tr>
            <td>
                Contact ID
            </td>
            <td>
                <%=Html.TextBox("SelectedUserContact.ContactID",Model.SelectedUserContact.ContactID) %>
                <%=Html.ValidationSummary("ContactID","*") %>
            </td>
        </tr>
        <tr>
            <td align="right">
                <input type="submit" value="Save" name="btnSave" id="btnSave" />
            </td>
            <td>
                <input type="button" value="Cancel" name="btnCancel" id="btnCancel" />
            </td>
        </tr>
    </table>
    <%} %>
    <script src="../../Scripts/jquery.validate.js" type="text/javascript"></script>
    <script language="javascript" type="text/javascript">

        $("#UserImportTypeForm").validate({
            rules:
    {

        "SelectedUserContact.FirstName": { required: true },
        "SelectedUserContact.LastName": { required: true },
        "SelectedUserContact.ContactID": {required:true}
    },
            messages:
    {

        "SelectedUserContact.FirstName": { required: "*" },
        "SelectedUserContact.LastName": { required: "*" },
        "SelectedUserContact.ContactID": { required: "*" },

    }
        });



    </script>
</asp:Content>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...