web-dev-qa-db-fra.com

Validation de déclenchement d'un champ lorsqu'un autre champ est modifié

J'ai une directive de validation personnalisée qui est appelée correctement lorsqu'un champ est modifié. Toutefois, la validité de ce champ dépend également de la valeur d'un autre champ. Ce deuxième champ est une liste de sélection si cela est important. 

Je me demandais s'il était possible de déclencher la validation manuellement lorsque le deuxième formulaire est modifié. Peut-être en utilisant l'événement ng-change. Quelle est la bonne façon de gérer quelque chose comme ça?

Voici ma directive:

angular.module('myApp', []).
    directive('validage', function () {
        return {
            require: 'ngModel',
            link: function (scope, elem, attr, ngModel) {

                function validate(value) {
                    var valid = true;
                    if ((GetDateDifference(new Date(value), new Date()) < 16 || GetDateDifference(new Date(value), new Date()) > 129)
                    && scope.dep.DependantType == "Spouse") {
                        valid = false;
                    }
                    ngModel.$setValidity('validage', valid);
                    return value;
                }

                //For DOM -> model validation
                ngModel.$parsers.unshift(function (value) {
                    var valid = true;
                    if ((GetDateDifference(new Date(value), new Date()) < 16 || GetDateDifference(new Date(value), new Date()) > 129)
                    && scope.dep.DependantType == "Spouse") {
                        valid = false;
                    }
                    ngModel.$setValidity('validage', valid);
                    return value;
                });

                //For model -> DOM validation
                ngModel.$formatters.unshift(function (value) {
                    var valid = true;
                    if ((GetDateDifference(new Date(value), new Date()) < 16 || GetDateDifference(new Date(value), new Date()) > 129)
                    && scope.dep.DependantType == "Spouse") {
                        valid = false;
                    }
                    ngModel.$setValidity('validage', valid);
                    return value;
                });
            }
        };
    });

Si vous êtes nouveau sur AngularJS, je vous recommande vivement de lire ces 2 articles: partie 1 & partie 2 . Ils donnent un aperçu des formulaires AngularJS.

27
PFranchise

Après avoir beaucoup cherché, j'ai découvert que nous pouvions déclencher la validation en appelant simplement $validate() dans le champ souhaité.
Ainsi, par exemple, si votre formulaire s'appelle my_form (c'est-à-dire que dans la balise, la balise de formulaire a un attribut name="my_form") et que le nom du champ que vous souhaitez valider est date (dans la balise, le champ de saisie a un attribut name="date"), puis, comme vous l'avez suggéré, vous pouvez utiliser l'événement ng-change du champ second et appeler $scope.my_form.date.$validate(); chaque fois que la fonction ng-change est appelée.

48
gneri

J'ai eu un problème similaire: deux champs de formulaire "intervalle" (pour $ scope.monitor.interval) et "timeout" (pour $ scope.monitor.timeout) avec la condition que timeout ne doit pas dépasser la moitié de l'intervalle. 

Tout d'abord, j'ai ajouté un validateur personnalisé à timeout qui vérifie cette condition. Maintenant, je devais déclencher le validateur de délai d'attente également lorsque l'intervalle changeait. J'ai atteint cet objectif en observant la propriété monitor.interval du modèle:

function EditMonitorCtrl($scope, $log, dialog, monitor) {
    $scope.monitor = monitor;

    ...

    // trigger validation of timeout field when interval changes
    $scope.$watch("monitor.interval", function() {
        if ($scope.editMonitorDlg.timeout.$viewValue) {          
            $scope.editMonitorDlg.timeout.$setViewValue($scope.editMonitorDlg.timeout.$viewValue);
        }
    });
}

Sans "si", la valeur de délai d'attente a été supprimée lors de l'initialisation du dialogue. 

3
stephanme

J'ai fini par ajouter la directive au deuxième champ, puis en le modifiant pour ajouter le message d'erreur au champ avec l'erreur. Il y a peut-être un meilleur moyen, mais c'est ce que j'ai fini par faire.

0
PFranchise

Je ne pouvais pas utiliser ng-blur="myForm.myField.$validate()" dans AngularJS 1.5, probablement parce que le modèle pour myField était vide. 

Cependant, ng-blur="myForm.myField.$setTouched()" a fonctionné. 

0
isherwood