@@ -541,20 +541,35 @@ angular.module('schemaForm').provider('schemaFormDecorators',
541541 return ( expression && $interpolate ( expression ) ( locals ) ) ;
542542 } ;
543543
544- //This works since we ot the ngModel from the array or the schema-validate directive.
544+ //This works since we get the ngModel from the array or the schema-validate directive.
545545 scope . hasSuccess = function ( ) {
546546 if ( ! scope . ngModel ) {
547547 return false ;
548548 }
549- return scope . ngModel . $valid &&
549+ if ( scope . options && scope . options . pristine &&
550+ scope . options . pristine . success === false ) {
551+ return scope . ngModel . $valid &&
552+ ! scope . ngModel . $pristine && ! scope . ngModel . $isEmpty ( scope . ngModel . $modelValue ) ;
553+ } else {
554+ return scope . ngModel . $valid &&
550555 ( ! scope . ngModel . $pristine || ! scope . ngModel . $isEmpty ( scope . ngModel . $modelValue ) ) ;
556+ }
551557 } ;
552558
553559 scope . hasError = function ( ) {
554560 if ( ! scope . ngModel ) {
555561 return false ;
556562 }
557- return scope . ngModel . $invalid && ! scope . ngModel . $pristine ;
563+ if ( ! scope . options || ! scope . options . pristine || scope . options . pristine . errors !== false ) {
564+ // Show errors in pristine forms. The default.
565+ // Note that "validateOnRender" option defaults to *not* validate initial form.
566+ // so as a default there won't be any error anyway, but if the model is modified
567+ // from the outside the error will show even if the field is pristine.
568+ return scope . ngModel . $invalid ;
569+ } else {
570+ // Don't show errors in pristine forms.
571+ return scope . ngModel . $invalid && ! scope . ngModel . $pristine ;
572+ }
558573 } ;
559574
560575 /**
@@ -1809,11 +1824,27 @@ angular.module('schemaForm').directive('sfArray', ['sfSelect', 'schemaForm', 'sf
18091824 scope . $on ( 'schemaFormValidate' , scope . validateArray ) ;
18101825
18111826 scope . hasSuccess = function ( ) {
1812- return ngModel . $valid && ! ngModel . $pristine ;
1827+ if ( scope . options && scope . options . pristine &&
1828+ scope . options . pristine . success === false ) {
1829+ return ngModel . $valid &&
1830+ ! ngModel . $pristine && ! ngModel . $isEmpty ( ngModel . $modelValue ) ;
1831+ } else {
1832+ return ngModel . $valid &&
1833+ ( ! ngModel . $pristine || ! ngModel . $isEmpty ( ngModel . $modelValue ) ) ;
1834+ }
18131835 } ;
18141836
18151837 scope . hasError = function ( ) {
1816- return ngModel . $invalid ;
1838+ if ( ! scope . options || ! scope . options . pristine || scope . options . pristine . errors !== false ) {
1839+ // Show errors in pristine forms. The default.
1840+ // Note that "validateOnRender" option defaults to *not* validate initial form.
1841+ // so as a default there won't be any error anyway, but if the model is modified
1842+ // from the outside the error will show even if the field is pristine.
1843+ return ngModel . $invalid ;
1844+ } else {
1845+ // Don't show errors in pristine forms.
1846+ return ngModel . $invalid && ! ngModel . $pristine ;
1847+ }
18171848 } ;
18181849
18191850 scope . schemaError = function ( ) {
@@ -1967,20 +1998,35 @@ angular.module('schemaForm').directive('sfField',
19671998 return ( expression && $interpolate ( expression ) ( locals ) ) ;
19681999 } ;
19692000
1970- //This works since we ot the ngModel from the array or the schema-validate directive.
2001+ //This works since we get the ngModel from the array or the schema-validate directive.
19712002 scope . hasSuccess = function ( ) {
19722003 if ( ! scope . ngModel ) {
19732004 return false ;
19742005 }
1975- return scope . ngModel . $valid &&
2006+ if ( scope . options && scope . options . pristine &&
2007+ scope . options . pristine . success === false ) {
2008+ return scope . ngModel . $valid &&
2009+ ! scope . ngModel . $pristine && ! scope . ngModel . $isEmpty ( scope . ngModel . $modelValue ) ;
2010+ } else {
2011+ return scope . ngModel . $valid &&
19762012 ( ! scope . ngModel . $pristine || ! scope . ngModel . $isEmpty ( scope . ngModel . $modelValue ) ) ;
2013+ }
19772014 } ;
19782015
19792016 scope . hasError = function ( ) {
19802017 if ( ! scope . ngModel ) {
19812018 return false ;
19822019 }
1983- return scope . ngModel . $invalid && ! scope . ngModel . $pristine ;
2020+ if ( ! scope . options || ! scope . options . pristine || scope . options . pristine . errors !== false ) {
2021+ // Show errors in pristine forms. The default.
2022+ // Note that "validateOnRender" option defaults to *not* validate initial form.
2023+ // so as a default there won't be any error anyway, but if the model is modified
2024+ // from the outside the error will show even if the field is pristine.
2025+ return scope . ngModel . $invalid ;
2026+ } else {
2027+ // Don't show errors in pristine forms.
2028+ return scope . ngModel . $invalid && ! scope . ngModel . $pristine ;
2029+ }
19842030 } ;
19852031
19862032 /**
@@ -2038,7 +2084,8 @@ angular.module('schemaForm').directive('sfField',
20382084 scope . $broadcast ( 'schemaFormValidate' ) ;
20392085 }
20402086 }
2041- } ) ;
2087+ }
2088+ ) ;
20422089
20432090 // Clean up the model when the corresponding form field is $destroy-ed.
20442091 // Default behavior can be supplied as a globalOption, and behavior can be overridden
@@ -2105,60 +2152,80 @@ angular.module('schemaForm').directive('sfMessage',
21052152 scope . $watch ( attrs . sfMessage , function ( msg ) {
21062153 if ( msg ) {
21072154 message = $sanitize ( msg ) ;
2108- if ( scope . ngModel ) {
2109- update ( scope . ngModel . $valid ) ;
2110- } else {
2111- update ( ) ;
2112- }
2155+ update ( ! ! scope . ngModel ) ;
21132156 }
21142157 } ) ;
21152158 }
21162159
2117- var update = function ( valid ) {
2118- if ( valid && ! scope . hasError ( ) ) {
2119- element . html ( message ) ;
2120- } else {
2121- var errors = [ ] ;
2122- angular . forEach ( ( ( scope . ngModel && scope . ngModel . $error ) || { } ) , function ( status , code ) {
2123- if ( status ) {
2124- // if true then there is an error
2125- // Angular 1.3 removes properties, so we will always just have errors.
2126- // Angular 1.2 sets them to false.
2127- errors . push ( code ) ;
2128- }
2129- } ) ;
2160+ var currentMessage ;
2161+ // Only call html() if needed.
2162+ var setMessage = function ( msg ) {
2163+ if ( msg !== currentMessage ) {
2164+ element . html ( msg ) ;
2165+ currentMessage = msg ;
2166+ }
2167+ } ;
21302168
2131- // In Angular 1.3 we use one $validator to stop the model value from getting updated.
2132- // this means that we always end up with a 'schemaForm' error.
2133- errors = errors . filter ( function ( e ) { return e !== 'schemaForm' ; } ) ;
2134-
2135- // We only show one error.
2136- // TODO: Make that optional
2137- var error = errors [ 0 ] ;
2138-
2139- if ( error ) {
2140- element . html ( sfErrorMessage . interpolate (
2141- error ,
2142- scope . ngModel . $modelValue ,
2143- scope . ngModel . $viewValue ,
2144- scope . form ,
2145- scope . options && scope . options . validationMessage
2146- ) ) ;
2169+ var update = function ( checkForErrors ) {
2170+ if ( checkForErrors ) {
2171+ if ( ! scope . hasError ( ) ) {
2172+ setMessage ( message ) ;
21472173 } else {
2148- element . html ( message ) ;
2174+ var errors = [ ] ;
2175+ angular . forEach ( scope . ngModel && scope . ngModel . $error , function ( status , code ) {
2176+ if ( status ) {
2177+ // if true then there is an error
2178+ // Angular 1.3 removes properties, so we will always just have errors.
2179+ // Angular 1.2 sets them to false.
2180+ errors . push ( code ) ;
2181+ }
2182+ } ) ;
2183+
2184+ // In Angular 1.3 we use one $validator to stop the model value from getting updated.
2185+ // this means that we always end up with a 'schemaForm' error.
2186+ errors = errors . filter ( function ( e ) { return e !== 'schemaForm' ; } ) ;
2187+
2188+ // We only show one error.
2189+ // TODO: Make that optional
2190+ var error = errors [ 0 ] ;
2191+
2192+ if ( error ) {
2193+ setMessage ( sfErrorMessage . interpolate (
2194+ error ,
2195+ scope . ngModel . $modelValue ,
2196+ scope . ngModel . $viewValue ,
2197+ scope . form ,
2198+ scope . options && scope . options . validationMessage
2199+ ) ) ;
2200+ } else {
2201+ setMessage ( message ) ;
2202+ }
21492203 }
2204+ } else {
2205+ setMessage ( message ) ;
21502206 }
21512207 } ;
21522208
21532209 // Update once.
21542210 update ( ) ;
21552211
2156- scope . $watchCollection ( 'ngModel.$error' , function ( ) {
2157- if ( scope . ngModel ) {
2158- update ( scope . ngModel . $valid ) ;
2212+ var once = scope . $watch ( 'ngModel' , function ( ngModel ) {
2213+ if ( ngModel ) {
2214+ // We also listen to changes of the model via parsers and formatters.
2215+ // This is since both the error message can change and given a pristine
2216+ // option to not show errors the ngModel.$error might not have changed
2217+ // but we're not pristine any more so we should change!
2218+ ngModel . $parsers . push ( function ( val ) { update ( true ) ; return val ; } ) ;
2219+ ngModel . $formatters . push ( function ( val ) { update ( true ) ; return val ; } ) ;
2220+ once ( ) ;
21592221 }
21602222 } ) ;
21612223
2224+ // We watch for changes in $error
2225+ scope . $watchCollection ( 'ngModel.$error' , function ( ) {
2226+ update ( ! ! scope . ngModel ) ;
2227+ } ) ;
2228+
21622229 }
21632230 } ;
21642231} ] ) ;
@@ -2619,11 +2686,13 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', '$parse
26192686 sfSelect ( path , scope . model , ngModel . $modelValue ) ;
26202687 } ) ;
26212688 } ) ;
2622- }
2689+ } ;
2690+
26232691
26242692 // Validate against the schema.
26252693
26262694 var validate = function ( viewValue ) {
2695+ //console.log('validate called', viewValue)
26272696 //Still might be undefined
26282697 if ( ! form ) {
26292698 return viewValue ;
@@ -2635,7 +2704,7 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', '$parse
26352704 }
26362705
26372706 var result = sfValidator . validate ( form , viewValue ) ;
2638-
2707+ //console.log('result is', result)
26392708 // Since we might have different tv4 errors we must clear all
26402709 // errors that start with tv4-
26412710 Object . keys ( ngModel . $error )
@@ -2690,6 +2759,7 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', '$parse
26902759 // updating if we've found an error.
26912760 if ( ngModel . $validators ) {
26922761 ngModel . $validators . schemaForm = function ( ) {
2762+ //console.log('validators called.')
26932763 // Any error and we're out of here!
26942764 return ! Object . keys ( ngModel . $error ) . some ( function ( e ) { return e !== 'schemaForm' ; } ) ;
26952765 } ;
@@ -2733,6 +2803,20 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', '$parse
27332803 }
27342804 } ;
27352805
2806+ var first = true ;
2807+ ngModel . $formatters . push ( function ( val ) {
2808+
2809+ // When a form first loads this will be called for each field.
2810+ // we usually don't want that.
2811+ if ( ngModel . $pristine && first &&
2812+ ( ! scope . options || scope . options . validateOnRender !== true ) ) {
2813+ first = false ;
2814+ return val ;
2815+ }
2816+ validate ( ngModel . $modelValue ) ;
2817+ return val ;
2818+ } ) ;
2819+
27362820 // Listen to an event so we can validate the input on request
27372821 scope . $on ( 'schemaFormValidate' , scope . validateField ) ;
27382822
0 commit comments