Manually adding & removing validation errors to jQuery validator

前端 未结 3 1642
北恋
北恋 2021-02-02 06:46

I have a search form & knockout-based grid for results. When search is performed, there is some server-side validation taking place on asp.net mvc, and if model state is not

相关标签:
3条回答
  • 2021-02-02 07:47

    I have solved this by overriding showErrors function in jQuery validator with my own, which is compatible with unobtrusive-generated validation spans, and cleaning up valid fields which have invalid class. It is not very nice workaround but it works.

    Here is jsfiddle with solution: http://jsfiddle.net/goranobradovic/ughCm/5/

    UPDATE: As link to external site is not proper answer according to site guidelines, I'm adding code sample here. For anyone already familiar with jQuery validation, just look at two lines of code in showErrors function. I assigned it to validator with validator.settings.showErrors = showErrors;.

    HTML:

    <form id="experiment" action="/" method="post">
    
    <fieldset>
      <legend></legend>
            <div class="editor-label">
              <label for="Email">Email</label>
            </div>
            <div class="editor-field">
    <input data-val="true" data-val-email="&amp;#39;Email&amp;#39; not valid email address." data-val-required="&amp;#39;Email&amp;#39; is mandatory." id="Email" name="Email" type="text" value=""><span class="field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>        
            </div>
            <div class="editor-label">
              <label for="FirstName">First name</label>
            </div>
            <div class="editor-field">
              <input class="text-box single-line" id="FirstName" name="FirstName" type="text" value="">
              <span class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="true"></span>
            </div>
    
            <div class="editor-label">
              <label for="LastName">Last name</label>
            </div>
            <div class="editor-field">
              <input class="text-box single-line" id="LastName" name="LastName" type="text" value="">
              <span class="field-validation-valid" data-valmsg-for="LastName" data-valmsg-replace="true"></span>
            </div>   
    </fieldset>
        <p>
            <button type="submit" class="save ui-button ui-widget ui-state-default ui-corner-all ui-button-text-icon-secondary" value="Save" role="button" aria-disabled="false"><span class="ui-button-text">Save</span><span class="ui-button-icon-secondary ui-icon ui-icon-disk"></span></button>
    
        </p>
    </form>
    <br/>
    
    <button id="add">Add error</button>
    <button id="remove">Remove error</button>
    
    <br/>
    <br/>
    Debug:
    <div id="debug"></div>
    

    JavaScript:

    var validator = {};
    
    function addError(e) {
        validator.showErrors({
            "FirstName": "test error"
        });
    }
    
    function removeError(e) {
        validator.showErrors({
            "FirstName": null
        });
        fixValidFieldStyles($("form"), validator);
    }
    
    $(document).ready(function() {
        var $form = $("#experiment");
        // prevent form submission
        $form.submit(function(e) {
            e.preventDefault();
            return false;
        });
        $("#add").click(addError);
        $("#remove").click(removeError);
        $("#debug").html("<h1>Validator properties:</h1>");
        validator = $form.validate();
        validator.settings.showErrors = showErrors;
        for (var i in validator) {
            var row = $("<span></span>").html(i).append("<br/>");
            $("#debug").append(row);
        }
    });
    
    
    function showErrors(errorMessage, errormap, errorlist) {
        var val = this;
        errormap.forEach(function(error, index) {
            val.settings.highlight.call(val, error.element, val.settings.errorClass, val.settings.validClass);
            $(error.element).siblings("span.field-validation-valid, span.field-validation-error").html($("<span></span>").html(error.message)).addClass("field-validation-error").removeClass("field-validation-valid").show();
        });
    }
    
    function fixValidFieldStyles($form, validator) {
        var errors = {};
        $form.find("input,select").each(function(index) {
            var name = $(this).attr("name");
            errors[name] = validator.errorsFor(name);
        });
        validator.showErrors(errors);
        var invalidFields = $form.find("." + validator.settings.errorClass);
        if (invalidFields.length) {
            invalidFields.each(function(index, field) {
                if ($(field).valid()) {
                    $(field).removeClass(validator.settings.errorClass);
                }
            });
        }
    }
    
    0 讨论(0)
  • 2021-02-02 07:49

    I did something a bit simpler - basically added the ability to more fully register the error into the validator. I added the following to jquery.validate.js (underneath showErrors):

    addErrors: function (errors) {
            for (var i = 0; i < errors.length; i++) {
                this.errorList.push({
                    element: $(errors[i].element)[0],
                    message: errors[i].message
                });
            }           
            this.showErrors();
        },
    

    then instead of calling form.validate().showErrors() you can do e.g.

    form.validate().addErrors([{
        element: $('#myinput'),
        message: 'A manual error message'
    }]);
    

    Finally because the form may not have been marked as invalid when submitted, you may want to force a validation on keyup or similar:

    $('#myinput').one('keyup', function(){ $(this).valid(); });
    

    (Note: this isn't battle-tested but I'm sure at the very least a solution lies down this way somewhere)

    0 讨论(0)
  • 2021-02-02 07:51

    I ended up solving the problem in a simple way cleaning the errors and then showing the new errors.

    // get the form inside we are working - change selector to your form as needed
    var $form = $("form");
    
    // get validator object
    var $validator = $form.validate();
    
    // get errors that were created using jQuery.validate.unobtrusive
    var $errors = $form.find(".field-validation-error span");
    
    // trick unobtrusive to think the elements were succesfully validated
    // this removes the validation messages
    $errors.each(function(){ $validator.settings.success($(this)); })
    
    // clear errors from validation
    $validator.resetForm();
    
    // Then show the errors
    $.validator().showErrors({prop:error}
    
    0 讨论(0)
提交回复
热议问题