最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use the Angular jQuery Validate's checkForm() function - Stack Overflow

programmeradmin0浏览0评论

EDIT:

I've added a JsFiddle so you can easily troubleshoot instead of having to set up the environment yourself. As you can see, validation is done on the Email field even before the blur event on the input element, which was triggered by the $scope.Email being changed. If you ment out the ng-show="!mainForm.validate()" on the <p> element, you'll see that the issue doesn't take place.


I am using the Angular implementation of jQuery Validate, and I am in need of the ability to check if a form is valid without showing the error messages. The standard solution I've seen online is to use jQuery Validate's checkForm() function, like this:

$('#myform').validate().checkForm()

However, the Angular wrapper I'm using doesn't currently implement the checkForm function. I have been trying to modify the source code to bring it in, and I'm afraid I'm in over my head. The code is small and simple enough that I'll paste it here:

(function (angular, $) {
    angular.module('ngValidate', [])

        .directive('ngValidate', function () {
            return {
                require: 'form',
                restrict: 'A',
                scope: {
                    ngValidate: '='
                },
                link: function (scope, element, attrs, form) {
                    var validator = element.validate(scope.ngValidate);

                    form.validate = function (options) {
                        var oldSettings = validator.settings;

                        validator.settings = $.extend(true, {}, validator.settings, options);

                        var valid = validator.form();

                        validator.settings = oldSettings; // Reset to old settings

                        return valid;
                    };

                    form.numberOfInvalids = function () {
                        return validator.numberOfInvalids();
                    };
                    
                    //This is the part I've tried adding in.
                    //It runs, but still shows error messages when executed.
                    //form.checkForm = function() {
                    //  return validator.checkForm();
                    //}
                }
            };
        })

        .provider('$validator', function () {
            $.validator.setDefaults({
                onsubmit: false // to prevent validating twice
            });

            return {
                setDefaults: $.validator.setDefaults,
                addMethod: $.validator.addMethod,
                setDefaultMessages: function (messages) {
                    angular.extend($.validator.messages, messages);
                },
                format: $.validator.format,
                $get: function () {
                    return {};
                }
            };
        });
}(angular, jQuery));

I want to be able to use it to show or hide a message, like this:

<p class="alert alert-danger" ng-show="!mainForm.checkForm()">Please correct any errors above before saving.</p>

The reason I don't just use !mainForm.validate() is because that causes the error messages to be shown on elements before they are "blurred" away from, which is what I'm trying to avoid. Can anyone help me implement the checkForm() function into this angular directive?

EDIT:

I've added a JsFiddle so you can easily troubleshoot instead of having to set up the environment yourself. As you can see, validation is done on the Email field even before the blur event on the input element, which was triggered by the $scope.Email being changed. If you ment out the ng-show="!mainForm.validate()" on the <p> element, you'll see that the issue doesn't take place.


I am using the Angular implementation of jQuery Validate, and I am in need of the ability to check if a form is valid without showing the error messages. The standard solution I've seen online is to use jQuery Validate's checkForm() function, like this:

$('#myform').validate().checkForm()

However, the Angular wrapper I'm using doesn't currently implement the checkForm function. I have been trying to modify the source code to bring it in, and I'm afraid I'm in over my head. The code is small and simple enough that I'll paste it here:

(function (angular, $) {
    angular.module('ngValidate', [])

        .directive('ngValidate', function () {
            return {
                require: 'form',
                restrict: 'A',
                scope: {
                    ngValidate: '='
                },
                link: function (scope, element, attrs, form) {
                    var validator = element.validate(scope.ngValidate);

                    form.validate = function (options) {
                        var oldSettings = validator.settings;

                        validator.settings = $.extend(true, {}, validator.settings, options);

                        var valid = validator.form();

                        validator.settings = oldSettings; // Reset to old settings

                        return valid;
                    };

                    form.numberOfInvalids = function () {
                        return validator.numberOfInvalids();
                    };
                    
                    //This is the part I've tried adding in.
                    //It runs, but still shows error messages when executed.
                    //form.checkForm = function() {
                    //  return validator.checkForm();
                    //}
                }
            };
        })

        .provider('$validator', function () {
            $.validator.setDefaults({
                onsubmit: false // to prevent validating twice
            });

            return {
                setDefaults: $.validator.setDefaults,
                addMethod: $.validator.addMethod,
                setDefaultMessages: function (messages) {
                    angular.extend($.validator.messages, messages);
                },
                format: $.validator.format,
                $get: function () {
                    return {};
                }
            };
        });
}(angular, jQuery));

I want to be able to use it to show or hide a message, like this:

<p class="alert alert-danger" ng-show="!mainForm.checkForm()">Please correct any errors above before saving.</p>

The reason I don't just use !mainForm.validate() is because that causes the error messages to be shown on elements before they are "blurred" away from, which is what I'm trying to avoid. Can anyone help me implement the checkForm() function into this angular directive?

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Feb 21, 2017 at 23:00 Jacob StammJacob Stamm 1,8733 gold badges36 silver badges57 bronze badges 8
  • Please stop inviting me to private chats if you're never going to respond to any of them. – Sparky Commented Mar 8, 2017 at 21:11
  • I'm sorry, but I did not receive any notifications that they were responded to. Believe me, I would have hopped on that immediately. The chat functionality is inconsistent and feels unfinished. My apologies. – Jacob Stamm Commented Mar 8, 2017 at 21:13
  • Let's cut to the chase: Ignoring everything else, and simply looking at your jsFiddle demo in the first edit, how is it that demo misbehaving and how should it perform instead? – Sparky Commented Mar 8, 2017 at 22:16
  • Seems like a case of "The XY Problem": meta.stackexchange./a/233676/157574 – Sparky Commented Mar 8, 2017 at 22:26
  • @Sparky The demo's misbehaving by doing validation while the user is typing, before the blur event on the input. Proper behavior is to do nothing until either the blur event occurs or you try to submit the form. My design differs in that I want to show the default in-line error messages in addition to my message at the bottom (very long pages in my app, and users are lost without a message right above the submit button). So, any change to the model runs a $digest cycle, which causes the validate() function in the ng-show of my custom error message to run, causing premature validation. – Jacob Stamm Commented Mar 9, 2017 at 13:30
 |  Show 3 more ments

6 Answers 6

Reset to default 1 +100

You can add checkForm() function to the plugin as following.

    (function (angular, $) {
    angular.module('ngValidate', [])

        .directive('ngValidate', function () {
            return {
                require: 'form',
                restrict: 'A',
                scope: {
                    ngValidate: '='
                },
                link: function (scope, element, attrs, form) {
                    var validator = element.validate(scope.ngValidate);

                    form.validate = function (options) {
                        var oldSettings = validator.settings;

                        validator.settings = $.extend(true, {}, validator.settings, options);

                        var valid = validator.form();

                        validator.settings = oldSettings; // Reset to old settings

                        return valid;
                    };

                    form.checkForm = function (options) {
                        var oldSettings = validator.settings;

                        validator.settings = $.extend(true, {}, validator.settings, options);

                        var valid = validator.checkForm();

                        validator.submitted = {};

                        validator.settings = oldSettings; // Reset to old settings

                        return valid;
                    };

                    form.numberOfInvalids = function () {
                        return validator.numberOfInvalids();
                    };
                }
            };
        })

        .provider('$validator', function () {
            $.validator.setDefaults({
                onsubmit: false // to prevent validating twice
            });

            return {
                setDefaults: $.validator.setDefaults,
                addMethod: $.validator.addMethod,
                setDefaultMessages: function (messages) {
                    angular.extend($.validator.messages, messages);
                },
                format: $.validator.format,
                $get: function () {
                    return {};
                }
            };
        });
}(angular, jQuery));

Please find the updated jsFiddle here https://jsfiddle/b2k4p3aw/

Reference: Jquery Validation: Call Valid without displaying errors?

If I understand your question correctly, you want to be able to show an error message when the email adress is invalid and you decide you want to show the error message.

You can achieve this by setting the input type to email like this <input type=email>

Angular adds an property to the form $valid so you can check in your controller if the submitted text is valid. So we only have to access this variable in the controller and invert it. (Because we want to show the error when it is not valid)

$scope.onSubmit = function() {
    // Decide here if you want to show the error message or not
    $scope.mainForm.unvalidSubmit = !$scope.mainForm.$valid
}

I also added a submit button that uses browser validation on submit. This way the onSubmit function won't even get called and the browser will show an error. These methods don't require anything except angularjs. You can check the updated JSFiddle here

Make sure to open your console to see when the onSubmit function gets called and what value gets send when you press the button.

You can use $touched, which is true as soon as the field is focused then blurred.

 <p class="alert alert-danger" ng-show="mainForm.Email.$touched && !mainForm.validate()">Please correct any errors above before saving.</p>

you can achieve onblur event with ng-show="mainForm.Email.$invalid && mainForm.Email.$touched" to <p> tag

by default mainForm.Email.$touched is false, on blur it will change to true

for proper validation change the <input> tag type to email

you can add ng-keydown="mainForm.Email.$touched=false" if you don't want to show error message on editing the input tag

I didn't used angular-validate.js plugin

<div ng-app="PageModule" ng-controller="MainController" class="container"><br />
  <form method="post" name="mainForm" ng-submit="OnSubmit(mainForm)" >
    <label>Email: 
      <input type="email" name="Email" ng-keydown="mainForm.Email.$touched=false" ng-model="Email" class="email" />
    </label><br />
    <p class="alert alert-danger" ng-show="mainForm.Email.$invalid && mainForm.Email.$touched">Please correct any errors above before saving.</p>
    <button type="submit">Submit</button>
  </form>
</div>

Updated code : JSFiddle

AngularJs Form Validation

More info on Angular validation


Update 2

checkForm will return whether the form is valid or invalid

// added checForm, also adds valid and invalid to angular
form.checkForm = function (){
    var valid =  validator.form();

    angular.forEach(validator.successList, function(value, key) {
     scope.$parent[formName][value.name].$setValidity(value.name,true);
    });

    angular.forEach(validator.errorMap, function(value, key) {
      scope.$parent[formName][key].$setValidity(key,false);
    });

    return valid
}

to hide default messages adding by jQuery validation plugin add below snippet, to $.validator.setDefaults

app.config(function ($validatorProvider) {
    $validatorProvider.setDefaults({
        errorPlacement: function(error,element) { // to hide default error messages
              return true;
           }
    });
});

here is the modified plugin looks like

(function (angular, $) {
angular.module('ngValidate', [])

    .directive('ngValidate', function () {
        return {
            require: 'form',
            restrict: 'A',
            scope: {
                ngValidate: '='
            },
            link: function (scope, element, attrs, form) {
                var validator = element.validate(scope.ngValidate);
                var formName = validator.currentForm.name;

                form.validate = function (options) {
                    var oldSettings = validator.settings;

                    validator.settings = $.extend(true, {}, validator.settings, options);

                    var valid = validator.form();

                    validator.settings = oldSettings; // Reset to old settings

                    return valid;
                };

                form.numberOfInvalids = function () {                           
                    return validator.numberOfInvalids();
                };

                // added checkForm
                form.checkForm = function (){
                    var valid =  validator.form();

                    angular.forEach(validator.successList, function(value, key) {
                     scope.$parent[formName][value.name].$setValidity(value.name,true);
                    });

                    angular.forEach(validator.errorMap, function(value, key) {
                      scope.$parent[formName][key].$setValidity(key,false);
                    });

                    return valid
                }
            }
        };
    })

    .provider('$validator', function () {
        $.validator.setDefaults({
            onsubmit: false // to prevent validating twice            
        });

        return {
            setDefaults: $.validator.setDefaults,
            addMethod: $.validator.addMethod,
            setDefaultMessages: function (messages) {
                angular.extend($.validator.messages, messages);
            },
            format: $.validator.format,
            $get: function () {
                return {};
            }
        };
    });
  }(angular, jQuery));

controller

app.controller("MainController", function($scope) {
$scope.Email = "";
$scope.url = "";
$scope.isFormInValid = false; // to hide validation messages
$scope.OnSubmit = function(form) {
    // here you can determine
    $scope.isFormInValid = !$scope.mainForm.checkForm(); 

     return false; 
 }
 })

need to have following on every input tag(example for email)

ng-show="isFormInValid && !mainForm.Email.$invalid "

if the form and email both are invalid the validation message shows up.

JSFiddle

try this code for validation this is the form

    <form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate>
    <div class="form-group">   
    <input  type="text"  ng-class="{ 'has-error' : userForm.name.$invalid &&    !userForm.name.$pristine }" ng-model="name" name="name" class="form-control" placeholder="{{ 'regName' | translate }}" required>
  <p ng-show="userForm.name.$invalid && !userForm.name.$pristine" class="help-block">Your name is required.</p>

  </div>

<div class="form-group">
  <input  type="tel" ng-class="{ 'has-error' : userForm.mob.$invalid && !userForm.mob.$pristine }" ng-model="mob" class="form-control" name="mob" ng-maxlength="11" ng-minlength="11"  ng-pattern="/^\d+$/"  placeholder="{{ 'regPhone' | translate }}" required>
       <p ng-show="userForm.mob.$invalid && !userForm.mob.$pristine" class="help-block">Enter a valid number</p>

  </div>
  <div class="form-group">
  <input  type="email"  ng-model="email" name="email" class="form-control" placeholder="{{ 'regEmail' | translate }}"   required>

<p ng-show="userForm.email.$invalid && !userForm.email.$pristine" class="help-block">Enter a valid email.</p>
</div>

<div class="form-group">
  <input   type="password" ng-model="pass" name="pass"  class="form-control" placeholder="{{ 'regPass' | translate }}" minlength="6" maxlength="16" required>
  <p ng-show="userForm.pass.$invalid && !userForm.pass.$pristine" class="help-block"> Too short Min:6 Max:16</p>


  <input  type="password" ng-model="repass"  class="form-control" ng-minlength="6" placeholder="{{ 'regConPass' | translate }}" ng-maxlength="16" required>
  </div>
 <button class="loginbtntwo" type="submit" id="regbtn2"  ng-disabled="userForm.$dirty && userForm.$invalid" translate="signUp" ></button>
  </form>

You will need to modify the Angular Validate Plugin a bit. Here is a working version of your code in JSFiddle. Note the updated plugin code as well as a pair of modifications to your original code.

Updated plugin code simply adds this to validator.SetDefaults parameter:

errorPlacement: function(error,element) { return true; } // to hide default error message

Then we use a scope variable to hide/show the custom error message:

$scope.OnSubmit = function(form) {
if (form.$dirty) {
    if (form.validate()) {
    //form submittal code
    } else {
    $scope.FormInvalid = true;
  }
}
发布评论

评论列表(0)

  1. 暂无评论