AngularJS: Comment définir manuellement l'entrée sur $ valide dans le contrôleur?

92

Utilisation de TokenInput plugin et utilisation de la validation formController intégrée à AngularJS.

En ce moment, j'essaie de vérifier si le champ contient du texte, puis définissez le champ sur valide si c'est le cas. Le problème avec l'utilisation du plugin est qu'il crée sa propre entrée, puis un ul + li pour stlying.

J'ai accès à addItem (formname) et à mes capacités dans le contrôleur, il me suffit de le définir sur $ valid.

Balisage.

<form class="form-horizontal add-inventory-item" name="addItem">
     <input id="capabilities" name="capabilities" token-input data-ng-model="inventoryCapabilitiesAutoComplete" data-on-add="addCapability()" data-on-delete="removeCapability()" required>
     <div class="required" data-ng-show="addItem.capabilities.$error.required" title="Please enter capability."></div>
</form>

JS.

$scope.capabilityValidation = function (capability) {
  if (capability.name !== "") {
    addItem.capabilities.$valid = true;
    addItem.capabilities.$error.required = false;
  } else {
    addItem.capabilities.$valid = false;
    addItem.capabilities.$error.required = true;
  }
};

J'exécute la fonction CapacityValidation lorsque TokenInput a quelque chose entré et passant dans l'objet.

ÉDITER:

J'ai découvert que ng-model sur mon entrée fait des choses et obtient les résultats de la saisie semi-automatique, c'est pourquoi je ne peux pas faire fonctionner ng-valid car il est basé sur le modèle.

$scope.inventoryCapabilitiesAutoComplete = {
  options: {
    tokenLimit: null
  },
  source: urlHelper.getAutoComplete('capability')
};

Je n'ai pas écrit cette implémentation de saisie semi-automatique, y a-t-il un autre moyen de le faire où j'aurais accès à l'attr ng-model et déplacer la fonction de modèle ailleurs?

Christopher Marshall
la source
1
Puisque votre plugin crée sa propre entrée et que vous avez écrit une fonction pour faire votre propre validation, pourquoi ne pas simplement utiliser votre propre propriété $ scope pour la validation aussi: <div ... data-ng-show="capabilities_error" ...> en d'autres termes, y a-t-il une raison pour laquelle vous voulez / devez utiliser FormController?
Mark Rajcok
2
Puisque tous mes autres formulaires l'utilisent, j'aimerais garder le contrôle qu'il donne. L'entrée créée par le plugin définit en fait la valeur dans mon entrée d'origine, que je dois ensuite vérifier dans ma validation, mais elle ne met pas à jour le formController lorsqu'il y a une valeur entrée.
Christopher Marshall
J'ai raccourci le balisage exprès pour isoler l'entrée. J'ai beaucoup plus d'entrées sous cette même forme.
Christopher Marshall
1
D'accord. Avez-vous essayé addItem.capabilities.$valid = trueet / ou défini addItem.capabilities. $ Error.required sur true ou false selon le cas?
Mark Rajcok
J'ai essayé les deux. Je mettrai à jour ma question pour vous montrer. Les $ valid et $ error.required s'affichent comme non définis sur mon point d'arrêt dans le contrôleur mais addItem.capabilities contient toujours des données.
Christopher Marshall

Réponses:

150

Vous ne pouvez pas modifier directement la validité d'un formulaire. Si toutes les entrées descendantes sont valides, le formulaire est valide, sinon, il ne l'est pas.

Ce que vous devez faire est de définir la validité de l'élément d'entrée. Ainsi;

addItem.capabilities.$setValidity("youAreFat", false);

Maintenant, l'entrée (et donc le formulaire) est invalide. Vous pouvez également voir quelle erreur provoque l'invalidation.

addItem.capabilities.errors.youAreFat == true;
Umur Kontacı
la source
1
Et si capabilitiesétait une variable? J'ai un tableau qui contient des noms d'entrée et je veux faire une boucle à l'intérieur du tableau et les définir invalides un par un: /
lightalex
1
Qu'entendez-vous par variable? Il est directement lié au formulaire lui-même, pas aux valeurs du formulaire. Il utilise l' nameattribut du formulaire et l' attribut d'entrée id. Ceci est différent des valeurs fixées parngModel
Umur Kontacı
11
J'ai trouvé la solution mais c'est ce que je voulais dire:$scope.addItem['myVariableName'].$setValidity("youAreFat", false);
lightalex
Après cela, il semble que certains champs de saisie ne sont plus valides en cas de changement ou de flou
Leonardo
4
Sur angulaire 1.4.7 et j'ai dû préfixer ce code avec $ scope ..$scope.addItem.capabilities.$setValidity("youAreFat", false);
Graham T
60

Les réponses ci-dessus ne m'ont pas aidé à résoudre mon problème. Après une longue recherche, je suis tombé sur cette solution partielle .

J'ai enfin résolu mon problème avec ce code pour définir manuellement le champ de saisie sur ng-invalid (pour le définir sur ng-valid, définissez-le sur `` true ''):

$scope.myForm.inputName.$setValidity('required', false);
notMyName
la source
3
J'ai fait la même chose et ça marche très bien. Mais maintenant j'ai quelques problèmes de revalidation du même domaine. Cela ne change pas à l'état changé, ce qui est très ennuyeux. J'utilise ng-model-options = "{updateOn: 'submit'}" pour valider en cliquant sur un bouton. Des pensées à ce sujet?
OliverKK
1
@OliverKK vous devrez appeler $setValidityavec truecomme deuxième paramètre chaque fois que l'entrée est valide.
Bernhard Hofmann
10
Cela n'a pas de sens d'utiliser rootscope, devrait juste être scope
Ryan M
1
J'ai essayé une solution similaire, mais le problème que j'ai trouvé est que si j'essaye ensuite de changer la valeur du contrôle dans le formulaire, il reste invalide. Dans mon cas, ce contrôle est une directive avec la sélection interne. Si je définis l'invalide pour ma directive (qui est ng-form), je ne peux pas supprimer ce statut invalide.
Naomi
18

Je suis tombé sur ce post avec un problème similaire. Ma solution consistait à ajouter un champ caché pour conserver mon état invalide pour moi.

<input type="hidden" ng-model="vm.application.isValid" required="" />

Dans mon cas, j'avais un bool nullable qu'une personne devait sélectionner l'un des deux boutons différents. s'ils répondent oui, une entité est ajoutée à la collection et l'état du bouton change. Tant que toutes les questions n'ont pas obtenu de réponse (l'un des boutons de chacune des paires a un clic), le formulaire n'est pas valide.

vm.hasHighSchool = function (attended) { 
  vm.application.hasHighSchool = attended;
  applicationSvc.addSchool(attended, 1, vm.application);
}
<input type="hidden" ng-model="vm.application.hasHighSchool" required="" />
<div class="row">
  <div class="col-lg-3"><label>Did You Attend High School?</label><label class="required" ng-hide="vm.application.hasHighSchool != undefined">*</label></div>
  <div class="col-lg-2">
    <button value="Yes" title="Yes" ng-click="vm.hasHighSchool(true)" class="btn btn-default" ng-class="{'btn-success': vm.application.hasHighSchool == true}">Yes</button>
    <button value="No" title="No" ng-click="vm.hasHighSchool(false)" class="btn btn-default" ng-class="{'btn-success':  vm.application.hasHighSchool == false}">No</button>
  </div>
</div>
James Fleming
la source
2

C'est très simple. Par exemple: dans votre contrôleur JS, utilisez ceci:

$scope.inputngmodel.$valid = false;

ou

$scope.inputngmodel.$invalid = true;

ou

$scope.formname.inputngmodel.$valid = false;

ou

$scope.formname.inputngmodel.$invalid = true;

Tout fonctionne pour moi pour des exigences différentes. Frappez si cela résout votre problème.

rahim.nagori
la source