Ненавязчивая проверка MVC на флажке не работает - PullRequest
22 голосов
/ 03 августа 2011

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

Это код Validator на стороне сервера, я добавил:

/// <summary>
/// Validation attribute that demands that a boolean value must be true.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value;
    }
}

Это модель

[MustBeTrue(ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }

Это мой взгляд:

@Html.EditorFor(x => x.AcceptTermsAndConditions)
@Html.LabelFor(x => x.AcceptTermsAndConditions)
@Html.ValidationMessageFor(x => x.AcceptTermsAndConditions)

и это jQuery, который я использовал для присоединения клиентской стороны валидатора:

$.validator.unobtrusive.adapters.addBool("mustbetrue", "required");

Однако клиентский сценарий не запускается. Всякий раз, когда я нажимаю кнопку отправки, проверка в других полях срабатывает нормально, но проверка условий и положений не срабатывает. Вот как выглядит код в Firebug после того, как я нажал кнопку отправки. 1017 *

<input type="checkbox" value="true" name="AcceptTermsAndConditions" id="AcceptTermsAndConditions" data-val-required="The I confirm that I am authorised to join this website and I accept the terms and conditions field is required." data-val="true" class="check-box">
<input type="hidden" value="false" name="AcceptTermsAndConditions">
<label for="AcceptTermsAndConditions">I confirm that I am authorised to join this website and I accept the terms and conditions</label>
<span data-valmsg-replace="true" data-valmsg-for="AcceptTermsAndConditions" class="field-validation-valid"></span>

Есть идеи? Я пропустил шаг? Это сводит меня с ума!

Заранее спасибо S

Ответы [ 6 ]

36 голосов
/ 03 августа 2011

Вам необходимо внедрить IClientValidatable в свой пользовательский атрибут, чтобы связать имя адаптера mustbetrue, которое вы регистрируете на стороне клиента, с этим атрибутом:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessage,
            ValidationType = "mustbetrue"
        };
    }
}

ОБНОВЛЕНИЕ:

Полный рабочий пример.

Модель:

public class MyViewModel
{
    [MustBeTrue(ErrorMessage = "You must accept the terms and conditions")]
    [DisplayName("Accept terms and conditions")]
    public bool AcceptsTerms { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel();
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

Вид:

@model MyViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    $.validator.unobtrusive.adapters.addBool("mustbetrue", "required");
</script>

@using (Html.BeginForm())
{
    @Html.CheckBoxFor(x => x.AcceptsTerms)
    @Html.LabelFor(x => x.AcceptsTerms)
    @Html.ValidationMessageFor(x => x.AcceptsTerms)
    <input type="submit" value="OK" />
}
25 голосов
/ 03 августа 2011

Sniffer,

В дополнение к реализации решения Дарина, вам также необходимо изменить файл jquery.validate.unobtrusive.js.В этом файле вы должны добавить метод проверки mustbetrue следующим образом:

$jQval.addMethod("mustbetrue", function (value, element, param) {
    // check if dependency is met
    if (!this.depend(param, element))
        return "dependency-mismatch";
    return element.checked;
});

Затем (сначала я забыл добавить это), вы также должны добавить следующее к jquery.validate.unobtrusive.js:

adapters.add("mustbetrue", function (options) {
    setValidationValues(options, "mustbetrue", true);
});

counsellorben

5 голосов
/ 24 апреля 2012

Я не уверен, почему это не сработало для меня, но я решил использовать ваш код и сделать что-то немного другое.

При загрузке JavaScript я добавляю следующее: это заставляет флажок запускать ненавязчивую проверку, если либо вы установите флажок, либо снимите его.Также, если вы отправите форму.

$(function () {
        $(".checkboxonblurenabled").change(function () {
            $('form').validate().element(this);
        });
});

Вам также необходимо добавить класс CSS к вашему флажку, например, так.

@Html.CheckBoxFor(model => model.AgreeToPrivacyPolicy, new { @class = "checkboxonblurenabled"})

Итак, теперь нам нужно подключить модель и добавить класс для обработкипроверка на стороне сервера (которую я использую сверху), но незначительное изменение ненавязчивости.

Вот атрибут customer, который расширяет IClientValidate, как в примере выше ...

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessage,
            ValidationType = "mustbetrue"
        };
    }
}

В вашей модели свойство объекта задает нужные нотации атрибутов

 [MustBeTrue(ErrorMessage = "Confirm you have read and agree to our privacy policy")]
    [Display(Name = "Privacy policy")]
    public bool AgreeToPrivacyPolicy { get; set; }

Хорошо, мы готовы добавить JavaScript.

(function ($) {
    /*
    START CHECK MUST BE TRUE - UNOBTRUSIVE JAVASCRIPT
    START CHECK MUST BE TRUE - UNOBTRUSIVE JAVASCRIPT
    START CHECK MUST BE TRUE - UNOBTRUSIVE JAVASCRIPT
    */
    jQuery.validator.unobtrusive.adapters.add("mustbetrue", ['maxint'], function (options) {
        options.rules["mustbetrue"] = options.params;
        options.messages["mustbetrue"] = options.message;
    });

    jQuery.validator.addMethod("mustbetrue", function (value, element, params) {

        if ($(element).is(':checked')) {
            return true;
        }
        else {
            return false;
        }
    });
    /*
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    */



} (jQuery));

Что делает эту работу, так это ... Что ж.Посмотрев на HTML-разметку после попытки предложить предложенный ответ выше, все мои значения были установлены в true, однако мой флажок отмечен как false.Итак, я решил позволить jQuery работать с IsChecked

2 голосов
/ 17 декабря 2013

Для тех, кто не работает ни одно из этих решений:

Я работаю с Razor MVC 4, используя .Net Framework 4 и последние файлы сценариев проверки jquery.

После реализациипроверка пользовательских атрибутов на стороне клиента и сервера, она все еще не работает.Моя форма в любом случае отправляется.

Итак, вот в чем загвоздка: JQuery validate скрипт имеет настройку по умолчанию игнорирования скрытых тегов, где скрыто http://api.jquery.com/hidden-selector/,, что обычно не будет проблемой, но @Используемый мной стиль Html.CheckBoxFor настроен с использованием стиля CSS3, который меняет отображение на none, и отображается нестандартное изображение флажка, поэтому оно никогда не выполнит правило проверки для флажка.

MyОбходной путь - добавление этой строки перед объявлением пользовательского правила проверки клиента:

$.validator.defaults.ignore = "";

переопределяет параметр игнорирования для всех проверок на текущей странице, обратите внимание, что теперь он может выполнять проверки и в скрытом поле (побочный эффект).

1 голос
/ 26 февраля 2014
<script>
    $(function () {
        $('#btnconfirm').click(function () {
            if ($("#chk").attr('checked') !== undefined ){
                return true;
            }
            else {

                alert("Please Select Checkbox ");
                return false;
            }
        });

    });
</script>
<div style="float: left">
                    <input type="checkbox" name="chk" id="chk"  />
                    I read and accept the terms and Conditions of registration
                </div>
  <input type="submit" value="Confirm"  id="btnconfirm" />
0 голосов
/ 31 декабря 2014
/// <summary> 
///  Summary : -CheckBox for or input type check required validation is not working the root cause and solution as follows
///
///  Problem :
///  The key to this problem lies in interpretation of jQuery validation 'required' rule. I digged a little and find a specific code inside a jquery.validate.unobtrusive.js file:
///  adapters.add("required", function (options) {
///  if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
///    setValidationValues(options, "required", true);
///    }
///   });
///   
///  Fix: (Jquery script fix at page level added in to check box required area)
///  jQuery.validator.unobtrusive.adapters.add("brequired", function (options) {
///   if (options.element.tagName.toUpperCase() == "INPUT" && options.element.type.toUpperCase() == "CHECKBOX") {
///              options.rules["required"] = true;
///   if (options.message) {
///                   options.messages["required"] = options.message;
///                       }
///  Fix : (C# Code for MVC validation)
///  You can see it inherits from common RequiredAttribute. Moreover it implements IClientValidateable. This is to make assure that rule will be propagated to client side (jQuery validation) as well.
///  
///  Annotation example :
///   [BooleanRequired]
///   public bool iAgree { get; set' }
///    

/// </summary>


public class BooleanRequired : RequiredAttribute, IClientValidatable
{

    public BooleanRequired()
    {
    }

    public override bool IsValid(object value)
    {
        return value != null && (bool)value == true;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        return new ModelClientValidationRule[] { new ModelClientValidationRule() { ValidationType = "brequired", ErrorMessage = this.ErrorMessage } };
    }
}
...