Tengo una tabla que se crea usando ng-repeat. Quiero agregar validación a cada elemento en la tabla. El problema es que cada celda de entrada tiene el mismo nombre que la celda arriba y debajo de ella. Intenté usar el {{$index}}
valor para nombrar las entradas, pero a pesar de que los literales de cadena en HTML parecen correctos, ahora funciona.
Aquí está mi código a partir de ahora:
<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>
He intentado eliminar el {{}}
índice, pero tampoco funciona. A partir de ahora, la propiedad de validación de la entrada funciona correctamente, pero el mensaje de error no se muestra.
¿Alguien tiene alguna sugerencia?
Editar: además de las excelentes respuestas a continuación, aquí hay un artículo de blog que cubre este tema con más detalle: http://www.thebhwgroup.com/blog/2014/08/angularjs-html-form-design-part-2 / /
fuente
Respuestas:
AngularJS se basa en nombres de entrada para exponer errores de validación.
Desafortunadamente, a partir de hoy, no es posible (sin usar una directiva personalizada) generar dinámicamente el nombre de una entrada. De hecho, al verificar los documentos de entrada podemos ver que el atributo de nombre acepta solo una cadena.
Para resolver el problema del 'nombre dinámico' necesita crear un formulario interno (vea ng-form ) :
La otra alternativa sería escribir una directiva personalizada para esto.
Aquí está el jsFiddle que muestra el uso del ngForm: http://jsfiddle.net/pkozlowski_opensource/XK2ZT/2/
fuente
ng-form
DOM elementos, por lo que el enlace a la otra pregunta por lo que no es relevante aquí.ng-repeat
está vinculado,table tr
entonces debe usarng-form="myname"
attr.Desde que se hizo la pregunta, el equipo de Angular ha resuelto este problema haciendo posible la creación dinámica de nombres de entrada.
Con Angular versión 1.3 y posterior , ahora puede hacer esto:
Manifestación
Angular 1.3 también introdujo ngMessages, una herramienta más poderosa para la validación de formularios. Puede usar la misma técnica con ngMessages:
fuente
$valid
propiedad para la entrada se vuelve incorrectamentefalse
Si no desea usar ng-form, puede usar una directiva personalizada que cambiará el atributo de nombre del formulario. Coloque esta directiva como un atributo en el mismo elemento que su modelo ng.
Si está utilizando otras directivas en conjunto, tenga cuidado de que no tengan establecida la propiedad "terminal"; de lo contrario, esta función no podrá ejecutarse (dado que tiene una prioridad de -1).
Por ejemplo, cuando use esta directiva con ng-options, debe ejecutar este parche mono de una línea: https://github.com/AlJohri/bower-angular/commit/eb17a967b7973eb7fc1124b024aa8b3ca540a155
A menudo me resulta útil usar ng-init para establecer $ index en un nombre de variable. Por ejemplo:
Esto cambia su expresión regular a:
Si tiene varias repeticiones ng anidadas, ahora puede usar estos nombres de variables en lugar de $ parent. $ Index.
Definición de "terminal" y "prioridad" de las directivas: https://docs.angularjs.org/api/ng/service/ $ compile # directive-definition-object
Comentario de Github sobre la necesidad de ng-option monkeypatch: https://github.com/angular/angular.js/commit/9ee2cdff44e7d496774b340de816344126c457b3#commitcomment-6832095 https://twitter.com/aljohri/status/48296354152031436
ACTUALIZAR:
También puede hacer que esto funcione con ng-form.
fuente
Use la directiva ng-form dentro de la etiqueta en la que está usando la directiva ng-repeat. Luego puede usar el ámbito creado por la directiva ng-form para hacer referencia a un nombre genérico. Por ejemplo:
Crédito a: http://www.benlesh.com/2013/03/angular-js-validating-form-elements-in.html
fuente
ng-form="formName"
a la etiqueta que tiene ng-repeat ... funcionó de maravilla :)Se agregó un ejemplo más complejo con "validación personalizada" en el lado del controlador http://jsfiddle.net/82PX4/3/
fuente
Al analizar estas soluciones, la que Al Johri proporcionó anteriormente es la más cercana a mis necesidades, pero su directiva era un poco menos programable de lo que quería. Aquí está mi versión de sus soluciones:
Esta solución le permite pasar una expresión de generador de nombres a la directiva y evita el bloqueo a la sustitución de patrones que estaba usando.
También tuve problemas inicialmente con esta solución, ya que no mostraba un ejemplo de uso en marcado, así que así es como la usé.
Tengo un ejemplo de trabajo más completo en github .
fuente
la validación funciona con ng repeat si uso la siguiente sintaxis
scope.step3Form['item[107][quantity]'].$touched
No sé si es una mejor práctica o la mejor solución, pero funcionafuente
Sobre la base de la respuesta de pkozlowski.opensource , he agregado una forma de tener nombres de entrada dinámicos que también funcionan con ngMessages . Tenga en cuenta la
ng-init
parte delng-form
elemento y el uso defurryName
.furryName
se convierte en el nombre de la variable que contiene el valor de la variable para elinput
'sname
atributo.fuente
Es demasiado tarde pero puede ser que pueda ayudar a cualquiera
fromname[uniquname].$error
Código de muestra:
Ver demostración de trabajo aquí
fuente
Si usa ng-repeat $ index funciona así
y
tenemos que mostrar el ng-show en ng-pattern
fuente
Es posible y así es como hago lo mismo con una tabla de entradas.
envolver la mesa en una forma así
Entonces solo usa esto
Tengo un formulario con directivas anidadas múltiples que contienen entradas, selecciones, etc. Todos estos elementos están encerrados en ng-repeats y valores de cadena dinámicos.
Así es como se usa la directiva:
Nota: puede agregar e indexar a la concatenación de cadenas si necesita serializar tal vez una tabla de entradas; que es lo que hice
Esto debería manejar muchas situaciones en las que simplemente no sabes dónde estará el formulario. ¿O quizás tiene formularios anidados, pero por alguna razón desea adjuntar este nombre de entrada a dos formularios? Bueno, simplemente pase el nombre del formulario al que desea adjuntar el nombre de entrada.
Lo que quería era una forma de asignar valores dinámicos a entradas que nunca sabré, y luego simplemente llamar a $ scope.myFormName. $ Valid.
Puede agregar cualquier otra cosa que desee: más tablas, más entradas de formularios, formularios anidados, lo que desee. Simplemente pase el nombre del formulario con el que desea validar las entradas. Luego, en el formulario de envío, pregunte si $ scope.yourFormName. $ Valid
fuente
Esto obtendrá el nombre en ng-repeat para aparecer por separado en la validación del formulario.
Pero tuve problemas para buscarlo en su mensaje de validación, así que tuve que usar un ng-init para resolver una variable como clave de objeto.
fuente
Aquí un ejemplo de cómo hago eso, no sé si es la mejor solución, pero funciona perfectamente.
Primero, el código en HTML. Mira ng-class, está llamando a la función hasError. Mire también la declaración del nombre de la entrada. Yo uso el $ index para crear diferentes nombres de entrada.
Y ahora, aquí está la función hasError:
fuente
Mis requisitos eran un poco diferentes a los que se hicieron en la pregunta original, pero espero poder ayudar a alguien que está pasando por el mismo problema que yo ...
Tenía que definir si un campo era obligatorio o no en función de una variable de alcance. Así que básicamente tuve que establecer
ng-required="myScopeVariable"
(que es una variable booleana).fuente