简体   繁体   中英

jquery validation engine's conditional validation

i have a form that uses Jquery validation engine as a validation library inside and Angular's SPA. The form has a check box and a text-box . i want that text-box should be required only if the check box is checked. this functionality seems to be working. but the problem is that my ng-submit function gets called even if there is a validation error.I want to restrict this call. i am using Angular's directive to validate and invalidate the controls.

            <form role="form" name="frmVariableConfig1" class="formValidVariableConfig1 form-inline" novalidate ng-submit="frmVariableConfig1.$valid && vm.saveChanges()">


                        <span class="checkableBox"><input type="checkbox" item="variable" toggle-selection="toggleSelection('1')" bootstrap-check ng-model="vm.SetThreshold"></span>


            <input type="text" ng-model="vm.Threshold" name="cntrlThresh" class="form-control input-sm {{ vm.getValidation(vm.SetThreshold) }}" placeholder="Threshold" check-validation2>

                  <button type="submit" class="btn btn-sm">Save</button>
        </form>   

vm.getValidation function returns "validate[required]" or "" as per the value of vm.SetThreshold which is the model of the check-box above.

directive is set like this

    .module('app').directive('checkValidation2', [
    function () {
        return {
            restrict: 'A',
            require: '?ngModel',
            link: function (scope, element, attrs, ngModel) {
                element.closest('form').validationEngine();

                scope.$watch(attrs.ngModel, function (newValue, oldValue) {
                    var valid = !element.validationEngine('validate');//check if the control is valid
                    ngModel.$setValidity(element.context.name, valid); //set validity accordingly. 
                    return valid;
                });
            }
        };
    }
]);

UPDATE

here is something that might help. on page load the form is ng-valid. fine because there is no validation injected in the text box..now i click the check box it injects the validation class in the text box but the form remains unchanged. ie it is still ng-valid. so now if i click the button cause form is valid the function is called.

and if i simply add validation class without the function call the form is invalid on page load and gets valid if the text box is filled. which is the expected behavior.

its looks like all is happening because i am injecting the validation dynamically. some how forms validations needs to be restarted after injection.

checkBox is using iCheck Plugin with a directive

angular.module('app').directive('checkValidation2', ['$compile',
function($compile) {
    return {
        restrict: 'A',
        require: '?ngModel',
        compile: function(ele, attr, ngModel) {
            ele.closest('form').validationEngine();
            //removing directive attribute to stop to go it to infinite loop
            //as we are compiling DOM again

            ele.removeAttr("check-Validation2");
            var compile = $compile(ele); //compiling object on prelink state
            return function(scope, element, attrs, ngModel) {
                compile(scope); //compiling dom in postlink phase
                scope.$watch(attrs.ngModel, function(newValue, oldValue) {
                    var valid = !element.validationEngine('validate'); //check if the control is valid
                    ngModel.$setValidity(element.context.name, valid); //set validity accordingly. 
                    return valid;
                });
            }

        }
    };
}

]);

As you are using controllerAs syntax your value is not inside a scope you need to bind that value inside a scope

$scope.$watch(angular.bind(this, function () {
    return this[attrs.ngModel]; // this will evaluate ng-model value from `this`
}), function (newVal, oldVal) {
     var valid = !element.validationEngine('validate');//check if the control is valid
     ngModel.$setValidity(element.context.name, valid); //set validity accordingly. 
     return valid;
});

Update

You should try to inject form validationEngine at compilation phase of the directive so that the changes will occur accurately in the DOM,

Directive

.module('app').directive('checkValidation2', [
    function() {
        return {
            restrict: 'A',
            require: '?ngModel',
            compile: function(ele, attr, ngModel) {
                ele.closest('form').validationEngine();
                //removing directive attribute to stop to go it to infinite loop
                //as we are compiling DOM again
                ele.removeAttr('checkValidation2');
                var compile = $compile(ele); //compiling object on prelink state
                return function(scope, element, attrs, ngModel) {
                    compile(scope); //compiling dom in postlink phase
                    scope.$watch(attrs.ngModel, function(newValue, oldValue) {
                        var valid = !element.validationEngine('validate'); //check if the control is valid
                        ngModel.$setValidity(element.context.name, valid); //set validity accordingly. 
                        return valid;
                    });
                }

            }
        };
    }
]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM