21

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

Это сервер код на стороне 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 после того, как я нажал кнопку отправки.

<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

+0

не могли бы вы просто использовать '['] из милиции атрибут вместо создания собственного 'MustBeTrueAttribute'? – Fred

ответ

24

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); 
}); 

advsellorben

+0

Это потрясающе, и что мне не хватало! Желаю, чтобы я мог указать как вы, так и Дарин в качестве ответа, но вы получите его, когда вы меня за финишную черту! Один последний вопрос, чтобы немного убрать это - есть ли способ добавить эти 2 части кода, изменить сценарий core unobtrusive.js? Я попытался изменить $ jQval.addMehod на $ .validator.addMethod и adapters.add на $ .validator.unobtrusive.adapters.add и вызывать их из внешнего файла сценария, но это не показалось чтобы работать. Любые идеи? – Sniffer

+0

Ах, извинения - я немного отвлекся от отметьте там. Это не совсем работает. Проверка теперь отображается как ошибка, если флажок не отмечен (отлично!), Но также показывается как недопустимый, если пользователь затем отправляется и проверяет флажок (не очень!). это теперь останавливает страницу от публикации, поскольку она считает, что все еще есть ошибка. Есть идеи? – Sniffer

+1

@Sniffer, извините, но это то, что происходит, когда я думаю, что у меня пятно, и не делайте двойной проверки. Строка «return this.checked;» был неправильным, и я его изменил. Я попробовал несколько способов вставить скрипт на страницу вместо изменения jquery.validate.unobtrusive.js, но ни один из них не был успешным. – counsellorben

35

Вы должны реализовать 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" /> 
} 
+0

Я, хотя у вас там был Данн (вы, конечно, меня больше по пути), но он все еще не работает на стороне клиента. Правильно ли работает JavaScript? $ .validator.unobtrusive.adapters.addBool ("mustbetrue", "required"); – Sniffer

+1

@Sniffer, см. Мое обновление для полного рабочего примера. –

+0

Dann - Я сделал все это, и я до сих пор не могу заставить мой пример работать.Проблема в том, что HTML для ввода всегда остается неизменным независимо от того, что (см. Html в исходном вопросе, хотя теперь появляется data-val-mustbetrue!). Значение data-val всегда равно true независимо от того, что даже при загрузке страницы. Это то, чего вы ожидаете? Я даже изменил свой javascript на $ .validator.unobtrusive.adapters.addBool ("mustbetrue"); и я все еще получаю атрибут data-val-required в HTML, чего я не ожидал ... Любые идеи? – Sniffer

5

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

На моей загрузке javascript я добавляю следующее: это делает флажок укрывать незаметную проверку, если вы установите флажок и снимите флажок. Кроме того, если вы отправляете форму.

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

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

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

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

Heres атрибут клиент, который расширяет 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, однако мой флажок был ложным. Итак, я решил разрешить jquery работать с IsChecked

Надеюсь, это поможет.

+0

* >> Я не уверен, почему это не сработало для меня * меня ни: D Но ваше решение является полным и совершенным. Благодарю вас. Отличная идея. +1 Приветствия. –

2

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

Я работаю с Razor MVC 4 с использованием .Net Framework 4 и последние файлы сценариев JQuery Validate.

После выполнения проверки пользовательского атрибута на стороне клиента и сервера он по-прежнему не работает. В любом случае моя форма.

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

моего обходной путь, добавив следующую строку перед объявлением пользовательского клиента правила проверки:

$.validator.defaults.ignore = ""; 

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

+0

Это убивало меня, пока я не вспомнил, что передняя часть использовала кучу пользовательских элементов пользовательского интерфейса, скрывая мой вход. Хакерное решение заключалось в том, чтобы позиционировать входной экран, а не скрывать его. – Zac

1
<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
/// <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 } }; 
    } 
} 
+0

<тип скрипта = "текст/JScript"> // Пользовательские JQuery проверка ненавязчивый сценарий и адаптеры jQuery.validator.unobtrusive.adapters.add ("brequired", функция (опции) {// brequired для флажков if (options.element.tagName.toUpperCase() == "INPUT" && options.element.type.toUpperCase() == "CHECKBOX") { // setValidationValues ​​(опции, "required", true); . rules ["required"] = true; if (options.message) { options.messages ["required"] = опции.сообщение; } } }); –