@@ -51,6 +51,81 @@ angular.module('schemaForm').provider('sfPath',
5151 } ;
5252} ] ) ;
5353
54+ /**
55+ * @ngdoc service
56+ * @name sfSelect
57+ * @kind function
58+ *
59+ */
60+ angular . module ( 'schemaForm' ) . factory ( 'sfSelect' , [ 'sfPath' , function ( sfPath ) {
61+ var numRe = / ^ \d + $ / ;
62+
63+ /**
64+ * @description
65+ * Utility method to access deep properties without
66+ * throwing errors when things are not defined.
67+ * Can also set a value in a deep structure, creating objects when missing
68+ * ex.
69+ * var foo = Select('address.contact.name',obj)
70+ * Select('address.contact.name',obj,'Leeroy')
71+ *
72+ * @param {string } projection A dot path to the property you want to get/set
73+ * @param {object } obj (optional) The object to project on, defaults to 'this'
74+ * @param {Any } valueToSet (opional) The value to set, if parts of the path of
75+ * the projection is missing empty objects will be created.
76+ * @returns {Any|undefined } returns the value at the end of the projection path
77+ * or undefined if there is none.
78+ */
79+ return function ( projection , obj , valueToSet ) {
80+ if ( ! obj ) {
81+ obj = this ;
82+ }
83+ //Support [] array syntax
84+ var parts = typeof projection === 'string' ? sfPath . parse ( projection ) : projection ;
85+
86+ if ( typeof valueToSet !== 'undefined' && parts . length === 1 ) {
87+ //special case, just setting one variable
88+ obj [ parts [ 0 ] ] = valueToSet ;
89+ return obj ;
90+ }
91+
92+ if ( typeof valueToSet !== 'undefined' &&
93+ typeof obj [ parts [ 0 ] ] === 'undefined' ) {
94+ // We need to look ahead to check if array is appropriate
95+ obj [ parts [ 0 ] ] = parts . length > 2 && numRe . test ( parts [ 1 ] ) ? [ ] : { } ;
96+ }
97+
98+ var value = obj [ parts [ 0 ] ] ;
99+ for ( var i = 1 ; i < parts . length ; i ++ ) {
100+ // Special case: We allow JSON Form syntax for arrays using empty brackets
101+ // These will of course not work here so we exit if they are found.
102+ if ( parts [ i ] === '' ) {
103+ return undefined ;
104+ }
105+ if ( typeof valueToSet !== 'undefined' ) {
106+ if ( i === parts . length - 1 ) {
107+ //last step. Let's set the value
108+ value [ parts [ i ] ] = valueToSet ;
109+ return valueToSet ;
110+ } else {
111+ // Make sure to create new objects on the way if they are not there.
112+ // We need to look ahead to check if array is appropriate
113+ var tmp = value [ parts [ i ] ] ;
114+ if ( typeof tmp === 'undefined' || tmp === null ) {
115+ tmp = numRe . test ( parts [ i + 1 ] ) ? [ ] : { } ;
116+ value [ parts [ i ] ] = tmp ;
117+ }
118+ value = tmp ;
119+ }
120+ } else if ( value ) {
121+ //Just get nex value.
122+ value = value [ parts [ i ] ] ;
123+ }
124+ }
125+ return value ;
126+ } ;
127+ } ] ) ;
128+
54129angular . module ( 'schemaForm' ) . provider ( 'schemaFormDecorators' ,
55130[ '$compileProvider' , 'sfPathProvider' , function ( $compileProvider , sfPathProvider ) {
56131 var defaultDecorator = '' ;
@@ -823,81 +898,6 @@ angular.module('schemaForm').provider('schemaForm',
823898
824899} ] ) ;
825900
826- /**
827- * @ngdoc service
828- * @name sfSelect
829- * @kind function
830- *
831- */
832- angular . module ( 'schemaForm' ) . factory ( 'sfSelect' , [ 'sfPath' , function ( sfPath ) {
833- var numRe = / ^ \d + $ / ;
834-
835- /**
836- * @description
837- * Utility method to access deep properties without
838- * throwing errors when things are not defined.
839- * Can also set a value in a deep structure, creating objects when missing
840- * ex.
841- * var foo = Select('address.contact.name',obj)
842- * Select('address.contact.name',obj,'Leeroy')
843- *
844- * @param {string } projection A dot path to the property you want to get/set
845- * @param {object } obj (optional) The object to project on, defaults to 'this'
846- * @param {Any } valueToSet (opional) The value to set, if parts of the path of
847- * the projection is missing empty objects will be created.
848- * @returns {Any|undefined } returns the value at the end of the projection path
849- * or undefined if there is none.
850- */
851- return function ( projection , obj , valueToSet ) {
852- if ( ! obj ) {
853- obj = this ;
854- }
855- //Support [] array syntax
856- var parts = typeof projection === 'string' ? sfPath . parse ( projection ) : projection ;
857-
858- if ( typeof valueToSet !== 'undefined' && parts . length === 1 ) {
859- //special case, just setting one variable
860- obj [ parts [ 0 ] ] = valueToSet ;
861- return obj ;
862- }
863-
864- if ( typeof valueToSet !== 'undefined' &&
865- typeof obj [ parts [ 0 ] ] === 'undefined' ) {
866- // We need to look ahead to check if array is appropriate
867- obj [ parts [ 0 ] ] = parts . length > 2 && numRe . test ( parts [ 1 ] ) ? [ ] : { } ;
868- }
869-
870- var value = obj [ parts [ 0 ] ] ;
871- for ( var i = 1 ; i < parts . length ; i ++ ) {
872- // Special case: We allow JSON Form syntax for arrays using empty brackets
873- // These will of course not work here so we exit if they are found.
874- if ( parts [ i ] === '' ) {
875- return undefined ;
876- }
877- if ( typeof valueToSet !== 'undefined' ) {
878- if ( i === parts . length - 1 ) {
879- //last step. Let's set the value
880- value [ parts [ i ] ] = valueToSet ;
881- return valueToSet ;
882- } else {
883- // Make sure to create new objects on the way if they are not there.
884- // We need to look ahead to check if array is appropriate
885- var tmp = value [ parts [ i ] ] ;
886- if ( typeof tmp === 'undefined' || tmp === null ) {
887- tmp = numRe . test ( parts [ i + 1 ] ) ? [ ] : { } ;
888- value [ parts [ i ] ] = tmp ;
889- }
890- value = tmp ;
891- }
892- } else if ( value ) {
893- //Just get nex value.
894- value = value [ parts [ i ] ] ;
895- }
896- }
897- return value ;
898- } ;
899- } ] ) ;
900-
901901/* Common code for validating a value against its form and schema definition */
902902/* global tv4 */
903903angular . module ( 'schemaForm' ) . factory ( 'sfValidator' , [ function ( ) {
@@ -1401,11 +1401,12 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSele
14011401 return form ;
14021402 } ;
14031403 var form = getForm ( ) ;
1404+
14041405 if ( form . copyValueTo ) {
14051406 ngModel . $viewChangeListeners . push ( function ( ) {
14061407 var paths = form . copyValueTo ;
14071408 angular . forEach ( paths , function ( path ) {
1408- sfSelect ( path , scope . model , ngModel . $modelValue ) ;
1409+ sfSelect ( path , scope . model , ngModel . $viewValue ) ;
14091410 } ) ;
14101411 } ) ;
14111412 }
0 commit comments