web-dev-qa-db-de.com

MVC unauffällige Validierung im Kontrollkästchen funktioniert nicht

Ich versuche den Code wie in diesem Beitrag erwähnt zu implementieren. Mit anderen Worten, ich versuche, eine unauffällige Validierung in einem Kontrollkästchen für Bedingungen und Bedingungen zu implementieren. Wenn der Benutzer das Kontrollkästchen nicht aktiviert hat, sollte die Eingabe als ungültig markiert werden. 

Dies ist der serverseitige Validatorcode, den ich hinzugefügt habe:

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

Dies ist das Modell

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

Das ist meine Ansicht:

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

und dies ist die jQuery, mit der ich den Validator-Client verbunden habe:

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

Das clientseitige Skript scheint jedoch nicht in Erscheinung zu treten. Jedes Mal, wenn ich auf die Schaltfläche zum Senden drücke, ist die Bestätigung für die anderen Felder in Ordnung, aber die Bestätigung für die Allgemeinen Geschäftsbedingungen scheint nicht in Kraft zu treten. So sieht der Code in Firebug aus, nachdem ich auf die Schaltfläche zum Senden geklickt habe.

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

Irgendwelche Ideen? Habe ich einen Schritt verpasst? Das bringt mich zum Töpfchen!

Vielen Dank im Vorraus S

22
Sniffer

Sniffer,

Neben der Implementierung von Darins Lösung müssen Sie auch die Datei jquery.validate.unobtrusive.js ändern. In dieser Datei müssen Sie eine Validierungsmethode "mustbetrue" wie folgt hinzufügen:

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

Dann (ich habe vergessen, dies zuerst hinzuzufügen), müssen Sie auch Folgendes zu jquery.validate.unobtrusive.js hinzufügen:

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

counsellorben

25
counsellorben

Sie müssen IClientValidatable in Ihr benutzerdefiniertes Attribut implementieren, um den Namen des mustbetrue-Adapters, den Sie auf der Clientseite registrieren, mit diesem Attribut zu verknüpfen:

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

AKTUALISIEREN:

Vollständiges Arbeitsbeispiel.

Modell:

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

Regler:

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

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

Aussicht:

@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" />
}
36
Darin Dimitrov

Ich bin mir nicht sicher, warum dies für mich nicht funktioniert hat, aber ich habe mich dafür entschieden, Ihren Code zu verwenden und etwas anderes zu tun. 

Bei meinem JavaScript-Ladevorgang füge ich Folgendes hinzu: Das Kontrollkästchen löst die unwiderrufliche Validierung aus, wenn Sie das Kontrollkästchen aktivieren und das Kontrollkästchen deaktivieren. Auch wenn Sie das Formular absenden. 

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

Sie müssen auch die CSS-Klasse zu Ihrem Kontrollkästchen hinzufügen.

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

Also müssen wir nun das Modell anschließen und out-Klassen einsetzen, um die serverseitige Validierung (die ich wieder von oben verwende) zu handhaben, aber die Unauffälligkeit etwas zu ändern.

Hier ist das Kundenattribut, das IClientValidate wie im obigen Beispiel erweitert ...

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

In Ihrem Modell legen Objekteigenschaften die gewünschten Attributnotationen fest

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

Okay, wir sind bereit, das JavaScript einzufügen.

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

Was macht diese Arbeit, ist ... gut. Nachdem ich die HTML-Markierung nach dem Versuch, die oben vorgeschlagene Antwort auszuführen, angesehen hatte, wurden alle Werte auf "true" gesetzt, mein Ankreuzfeld war jedoch "false". Also entschied ich mich, jQuery mit IsChecked ausarbeiten zu lassen

5
Adam

Für die, die keine dieser Lösungen funktioniert:

Ich arbeite mit Razor MVC 4 unter Verwendung von .Net Framework 4, und die neuesten Jquery-Überprüfungsskriptdateien.

Nach der Implementierung der benutzerdefinierten Attributüberprüfung auf Client- und Serverseite funktioniert es immer noch nicht. Mein Formular wird sowieso veröffentlicht.

Hier ist der Haken: Das JQuery-Validierungsskript verfügt über die Standardeinstellung zum Ignorieren verborgener Tags, bei denen verborgen ist http://api.jquery.com/hidden-selector/ Normalerweise ein Problem, aber der von mir verwendete @ Html.CheckBoxFor-Stil wird mit einem CSS3-Stil angepasst, der die Anzeige in "none" ändert. Ein benutzerdefiniertes Bild des Kontrollkästchens wird angezeigt, sodass die Überprüfungsregel niemals im Kontrollkästchen ausgeführt wird.

Meine Problemumgehung bestand darin, diese Zeile vor der Deklaration der benutzerdefinierten Validierungsregel für Clients hinzuzufügen:

$.validator.defaults.ignore = "";

dabei wird die Ignore-Einstellung für alle Validierungen auf der aktuellen Seite überschrieben. Beachten Sie, dass jetzt Validierungen auch für ausgeblendete Felder ausgeführt werden können (ein Nebeneffekt).

2
Jesus Mogollon
<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
kavitha Reddy
/// <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 } };
    }
}