MVC unobtrusive Walidacja na checkbox nie działa

Próbuję zaimplementować Kod jak wspomniano w Ten post . Innymi słowy, próbuję zaimplementować dyskretną walidację w polu wyboru warunków. Jeżeli użytkownik nie zaznaczył pola wyboru, wtedy Dane wejściowe powinny być oznaczone jako nieprawidłowe.

To jest kod walidatora po stronie serwera, dodałem:

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

To jest model

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

To jest moje zdanie:

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

I to jest jQuery, którego użyłem do podłączenia klienta walidatora Strona:

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

Skrypt po stronie klienta nie wydaje się jednak działać. Za każdym razem, gdy naciskam przycisk Wyślij, Walidacja w innych polach działa dobrze, ale Walidacja dla warunków nie wydaje się działać. Tak wygląda kod w Firebug po kliknięciu przycisku submit.

<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>
Jakieś pomysły? Przegapiłem jakiś krok? To doprowadza mnie do nocnika! Z góry dzięki S
Author: Community, 2011-08-03

6 answers

Sniffer,

Oprócz implementacji rozwiązania Darin, musisz również zmodyfikować plik jquery.validate.unobtrusive.js. W tym pliku należy dodać metodę walidacji "mustbetrue" w następujący sposób:

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

Następnie (zapomniałem dodać to na początku), należy również dodać do jquery.validate.unobtrusive.js:

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

Doradca

 24
Author: counsellorben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-04 12:00:51

Musisz zaimplementować IClientValidatable na swoim niestandardowym atrybutie, aby powiązać nazwę adaptera mustbetrue, który rejestrujesz po stronie klienta z tym atrybutem:

[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"
        };
    }
}

Aktualizacja:

Pełny przykład pracy.

Model:

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

Kontroler:

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

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

Widok:

@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" />
}
 35
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-03 11:01:52

Nie jestem pewien, dlaczego to nie działa dla mnie, ale zdecydowałem się użyć Twojego kodu i zrobić coś nieco innego.

Na moim ładowaniu javascript dodaję następujące, to sprawia, że checkbox odpalić unabtrusive walidacji, jeśli, albo wybrać pole wyboru i odznaczyć go. Również, jeśli przesyłasz formularz.

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

Musisz również dodać klasę CSS do swojego checkboxa, w ten sposób.

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

Więc teraz musimy podłączyć model i umieścić klasę out do obsługi walidacji po stronie serwera (które ponownie wykorzystuję z góry), ale zmieniając nieco dyskretność.

Heres atrybut klienta, który rozszerza IClientValidate jak w powyższym przykładzie...

[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"
        };
    }
}

W modelu właściwość obiektu ustaw żądane notacje atrybutów

 [MustBeTrue(ErrorMessage = "Confirm you have read and agree to our privacy policy")]
    [Display(Name = "Privacy policy")]
    public bool AgreeToPrivacyPolicy { get; set; }
/ Align = "left" /
(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));
Co sprawia, że to działa, jest... cóż. Po spojrzeniu na znaczniki HTML po próbie wykonania sugerowanej odpowiedzi powyżej, moje wartości zostały ustawione na true, jednak moje pole wyboru zaznaczone było fałszywe. Więc, postanowiłem pozwolić jquery pracować to za pomocą IsChecked Mam nadzieję, że to pomoże.
 5
Author: Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-24 15:41:51

Dla tych, których żadne z tych rozwiązań nie działa:

Pracuję z Razor MVC 4 przy użyciu. Net Framework 4, A Najnowsze pliki skryptów jQuery sprawdzają poprawność.

Po zaimplementowaniu walidacji atrybutów niestandardowych po stronie klienta i serwera nadal nie działa. Mój formularz i tak zostanie wysłany.

Więc tutaj jest haczyk: Skrypt jQuery validate ma domyślne ustawienie ignoruj Ukryte tagi, gdzie ukryty jest http://api.jquery.com/hidden-selector / , to nie będzie problem normalnie ale @Html.CheckBoxFor style, którego używam, jest dostosowywany za pomocą stylu CSS3, który zmienia wyświetlanie na brak i wyświetlany jest niestandardowy obraz pola wyboru, więc nigdy nie wykona reguły walidacji na polu wyboru.

Moje obejście polegało na dodaniu tej linii przed deklaracją custom client validation rule:

$.validator.defaults.ignore = "";

To, co robi, to nadpisuje ustawienie ignoruj dla wszystkich walidacji na bieżącej stronie, zauważ, że teraz może wykonywać walidacje na hidden pole zbyt (efekt uboczny).

 2
Author: Jesus Mogollon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-17 20:23:56
<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" />
 1
Author: kavitha Reddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-26 11:19:44
 /// <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
Author: dhandapani harikrishnan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-31 09:54:33