11/**
22 * Directive that handles the model arrays
33 */
4- angular . module ( 'schemaForm' ) . directive ( 'sfArray' , [ 'sfSelect' , 'schemaForm' ,
5- function ( sfSelect , schemaForm ) {
4+ angular . module ( 'schemaForm' ) . directive ( 'sfArray' , [ 'sfSelect' , 'schemaForm' , 'sfValidator' ,
5+ function ( sfSelect , schemaForm , sfValidator ) {
66
77 var setIndex = function ( index ) {
88 return function ( form ) {
@@ -15,7 +15,8 @@ function(sfSelect, schemaForm) {
1515 return {
1616 restrict : 'A' ,
1717 scope : true ,
18- link : function ( scope , element , attrs ) {
18+ require : '?ngModel' ,
19+ link : function ( scope , element , attrs , ngModel ) {
1920 var formDefCache = { } ;
2021
2122 // Watch for the form definition and then rewrite it.
@@ -74,21 +75,31 @@ function(sfSelect, schemaForm) {
7475 } ) ;
7576
7677 // If there are no defaults nothing is added so we need to initialize
77- // the array. null for basic values, {} or [] for the others.
78+ // the array. undefined for basic values, {} or [] for the others.
7879 if ( len === list . length ) {
7980 var type = sfSelect ( 'schema.items.type' , form ) ;
80- var dflt = null ;
81+ var dflt ;
8182 if ( type === 'object' ) {
8283 dflt = { } ;
8384 } else if ( type === 'array' ) {
8485 dflt = [ ] ;
8586 }
8687 list . push ( dflt ) ;
8788 }
89+
90+ // Trigger validation.
91+ if ( scope . validateArray ) {
92+ scope . validateArray ( ) ;
93+ }
8894 } ;
8995
9096 scope . deleteFromArray = function ( index ) {
9197 list . splice ( index , 1 ) ;
98+
99+ // Trigger validation.
100+ if ( scope . validateArray ) {
101+ scope . validateArray ( ) ;
102+ }
92103 } ;
93104
94105 // Always start with one empty form unless configured otherwise.
@@ -107,9 +118,6 @@ function(sfSelect, schemaForm) {
107118 if ( form . titleMap && form . titleMap . length > 0 ) {
108119 scope . titleMapValues = [ ] ;
109120
110-
111-
112-
113121 // We watch the model for changes and the titleMapValues to reflect
114122 // the modelArray
115123 var updateTitleMapValues = function ( arr ) {
@@ -146,6 +154,55 @@ function(sfSelect, schemaForm) {
146154 } ) ;
147155 }
148156
157+
158+ // If there is a ngModel present we need to validate when asked.
159+ if ( ngModel ) {
160+ var error ;
161+
162+ scope . validateArray = function ( ) {
163+ // The actual content of the array is validated by each field
164+ // so we settle for checking validations specific to arrays
165+
166+ // Since we prefill with empty arrays we can get the funny situation
167+ // where the array is required but empty in the gui but still validates.
168+ // Thats why we check the length.
169+ var result = sfValidator . validate (
170+ form ,
171+ scope . modelArray . length > 0 ? scope . modelArray : undefined
172+ ) ;
173+ if ( result . valid === false &&
174+ result . error &&
175+ ( result . error . dataPath === '' ||
176+ result . error . dataPath === '/' + form . key [ form . key . length - 1 ] ) ) {
177+
178+ // Set viewValue to trigger $dirty on field. If someone knows a
179+ // a better way to do it please tell.
180+ ngModel . $setViewValue ( scope . modelArray ) ;
181+ error = result . error ;
182+ ngModel . $setValidity ( 'schema' , false ) ;
183+
184+ } else {
185+ ngModel . $setValidity ( 'schema' , true ) ;
186+ }
187+ } ;
188+
189+ scope . $on ( 'schemaFormValidate' , scope . validateArray ) ;
190+
191+
192+ scope . hasSuccess = function ( ) {
193+ return ngModel . $valid && ! ngModel . $pristine ;
194+ } ;
195+
196+ scope . hasError = function ( ) {
197+ return ngModel . $invalid ;
198+ } ;
199+
200+ scope . schemaError = function ( ) {
201+ return error ;
202+ } ;
203+
204+ }
205+
149206 once ( ) ;
150207 } ) ;
151208 }
0 commit comments