171 votes

Comment valider des entrées créées dynamiquement à l'aide de ng-repeat, ng-show (angular)

J'ai un tableau qui est créé en utilisant ng-repeat. Je veux ajouter la validation à chaque élément du tableau. Le problème est que chaque cellule de saisie porte le même nom que la cellule située au-dessus et au-dessous d'elle. J'ai essayé d'utiliser la fonction {{$index}} pour nommer les entrées, mais bien que les littéraux de chaîne en HTML semblent corrects, cela fonctionne maintenant.

Voici mon code à ce jour :

<tr ng-repeat="r in model.BSM ">
   <td>
      <input ng-model="r.QTY" class="span1" name="QTY{{$index}}" ng-pattern="/^[\d]*\.?[\d]*$/" required/>
      <span class="alert-error" ng-show="form.QTY{{$index}}.$error.pattern"><strong>Requires a number.</strong></span>
      <span class="alert-error" ng-show="form.QTY{{$index}}.$error.required"><strong>*Required</strong></span>
   </td>
</tr>

J'ai essayé de retirer le {{}} à partir de l'index, mais cela ne fonctionne pas non plus. Pour l'instant, la propriété de validation de l'entrée fonctionne correctement, mais le message d'erreur ne s'affiche pas.

Quelqu'un a-t-il des suggestions ?

Edit : En plus des excellentes réponses ci-dessous, voici un article de blog qui traite de cette question de manière plus détaillée : http://www.thebhwgroup.com/blog/2014/08/angularjs-html-form-design-part-2/

5 votes

Pour ceux qui lisent ceci en 2015... la réponse la plus votée n'est plus la bonne. Regardez plus bas. :)

0 votes

Ce site semble être la réponse "pour 2015" dont parle @WillStrohl.

0 votes

Quelle est l'étiquette appropriée pour les SO ici ? Devrais-je laisser la réponse acceptée puisqu'elle était correcte à l'époque ou accepter la réponse correcte d'aujourd'hui ? Je veux juste que ce fil apparemment populaire soit utile aux nouveaux visiteurs.

1voto

Vlad Vinnikov Points 1317

La validation fonctionne avec ng repeat si j'utilise la syntaxe suivante scope.step3Form['item[107][quantity]'].$touched Je ne sais pas si c'est une bonne pratique ou la meilleure solution, mais ça marche.

<tr ng-repeat="item in items">
   <td>
        <div class="form-group">
            <input type="text" ng-model="item.quantity" name="item[<% item.id%>][quantity]" required="" class="form-control" placeholder = "# of Units" />
            <span ng-show="step3Form.$submitted || step3Form['item[<% item.id %>][quantity]'].$touched">
                <span class="help-block" ng-show="step3Form['item[<% item.id %>][quantity]'].$error.required"> # of Units is required.</span>
            </span>
        </div>
    </td>
</tr>

1voto

ABCD.ca Points 235

En s'appuyant sur le site de pkozlowski.opensource réponse j'ai ajouté un moyen d'avoir des noms d'entrée dynamiques qui fonctionnent aussi avec ngMessages . Notez le ng-init partie sur le ng-form et l'utilisation de l'élément furryName . furryName devient le nom de la variable qui contient la valeur de la variable pour l'élément input 's name attribut.

<ion-item ng-repeat="animal in creatures track by $index">
<ng-form name="animalsForm" ng-init="furryName = 'furry' + $index">
        <!-- animal is furry toggle buttons -->
        <input id="furryRadio{{$index}}"
               type="radio"
               name="{{furryName}}"
               ng-model="animal.isFurry"
               ng-value="radioBoolValues.boolTrue"
               required
                >
        <label for="furryRadio{{$index}}">Furry</label>

        <input id="hairlessRadio{{$index}}"
               name="{{furryName}}"
               type="radio"
               ng-model="animal.isFurry"
               ng-value="radioBoolValues.boolFalse"
               required
               >
        <label for="hairlessRadio{{$index}}">Hairless</label>

        <div ng-messages="animalsForm[furryName].$error"
             class="form-errors"
             ng-show="animalsForm[furryName].$invalid && sectionForm.$submitted">
            <div ng-messages-include="client/views/partials/form-errors.ng.html"></div>
        </div>
</ng-form>
</ion-item>

1voto

David Martin Points 21

Voici un exemple de la façon dont je fais cela, je ne sais pas si c'est la meilleure solution, mais elle fonctionne parfaitement.

D'abord, le code en HTML. Regardez ng-class, il appelle la fonction hasError. Regardez aussi la déclaration du nom de l'entrée. J'utilise le $index pour créer différents noms d'entrée.

<div data-ng-repeat="tipo in currentObject.Tipo"
    ng-class="{'has-error': hasError(planForm, 'TipoM', 'required', $index) || hasError(planForm, 'TipoM', 'maxlength', $index)}">
    <input ng-model="tipo.Nombre" maxlength="100" required
        name="{{'TipoM' + $index}}"/>

Et maintenant, voici la fonction hasError :

$scope.hasError = function (form, elementName, errorType, index) {
           if (form == undefined
               || elementName == undefined
               || errorType == undefined
               || index == undefined)
               return false;

           var element = form[elementName + index];
           return (element != null && element.$error[errorType] && element.$touched);
       };

1voto

Ali Adravi Points 932

Il est trop tard mais peut-être que cela peut aider quelqu'un.

  1. Créer un nom unique pour chaque contrôle
  2. Validez en utilisant fromname[uniquname].$error

Exemple de code :

<input 
    ng-model="r.QTY" 
    class="span1" 
    name="QTY{{$index}}" 
    ng-pattern="/^[\d]*\.?[\d]*$/" required/>
<div ng-messages="formName['QTY' +$index].$error"
     ng-show="formName['QTY' +$index].$dirty || formName.$submitted">
   <div ng-message="required" class='error'>Required</div>
   <div ng-message="pattern" class='error'>Invalid Pattern</div>
</div>

Voir le travail Démonstration ici

1voto

Kondal Points 1158

Si vous utilisez ng-repeat $index fonctionne comme ceci

  name="QTY{{$index}}"

et

   <td>
       <input ng-model="r.QTY" class="span1" name="QTY{{$index}}" ng-            
        pattern="/^[\d]*\.?[\d]*$/" required/>
        <span class="alert-error" ng-show="form['QTY' + $index].$error.pattern">
        <strong>Requires a number.</strong></span>
        <span class="alert-error" ng-show="form['QTY' + $index].$error.required">
       <strong>*Required</strong></span>
    </td>

nous devons montrer le ng-show dans le ng-pattern

   <span class="alert-error" ng-show="form['QTY' + $index].$error.pattern">
   <span class="alert-error" ng-show="form['QTY' + $index].$error.required">

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X