@@ -25,30 +25,37 @@ qx.Class.define("osparc.component.form.json.JsonSchemaForm", {
2525    ] ) ; 
2626    ajvLoader . addListener ( "ready" ,  e  =>  { 
2727      this . __ajv  =  new  Ajv ( ) ; 
28-       osparc . utils . Utils . fetchJSON ( schemaUrl ) 
29-         . then ( schema  =>  { 
30-           if  ( this . __validate ( schema . $schema ,  schema ) )  { 
31-             // If schema is valid 
32-             if  ( data  &&  this . __validate ( schema ,  data ) )  { 
33-               // Validate data if present 
34-               this . __data  =  data ; 
28+       if  ( schemaUrl )  { 
29+         osparc . utils . Utils . fetchJSON ( schemaUrl ) 
30+           . then ( schema  =>  { 
31+             if  ( this . __validate ( schema . $schema ,  schema ) )  { 
32+               // If schema is valid 
33+               this . __schema  =  schema ; 
34+               if  ( data  &&  this . __validate ( this . __schema ,  data ) )  { 
35+                 // Data is valid 
36+                 this . __data  =  data ; 
37+               } 
38+               return  this . __schema ; 
3539            } 
36-             return  schema ; 
37-           } 
38-           return  null ; 
39-         } ) 
40-         . then ( this . __render ) 
41-         . catch ( err  =>  { 
42-           console . error ( err ) ; 
43-           this . __render ( null ) ; 
44-         } ) ; 
40+             return  null ; 
41+           } ) 
42+           . then ( this . __render ) 
43+           . catch ( err  =>  { 
44+             console . error ( err ) ; 
45+           } ) ; 
46+       } 
47+       if  ( data )  { 
48+         this . setData ( data ) ; 
49+       } 
50+       this . fireEvent ( "ajvReady" ) ; 
4551    } ,  this ) ; 
4652    ajvLoader . addListener ( "failed" ,  console . error ,  this ) ; 
4753    this . __render  =  this . __render . bind ( this ) ; 
4854    ajvLoader . start ( ) ; 
4955  } , 
5056  events : { 
5157    "ready" : "qx.event.type.Event" , 
58+     "ajvReady" : "qx.event.type.Event" , 
5259    "submit" : "qx.event.type.Data" 
5360  } , 
5461  members : { 
@@ -72,7 +79,7 @@ qx.Class.define("osparc.component.form.json.JsonSchemaForm", {
7279        this . __submitBtn  =  new  osparc . ui . form . FetchButton ( this . tr ( "Submit" ) ) ; 
7380        this . __submitBtn . addListener ( "execute" ,  ( )  =>  { 
7481          if  ( this . __isValidData ( ) )  { 
75-             const  formData  =  this . toObject ( ) ; 
82+             const  formData  =  this . toObject ( schema ) ; 
7683            if  ( this . __validate ( schema ,  formData . json ) )  { 
7784              this . fireDataEvent ( "submit" ,  formData ) ; 
7885            } 
@@ -131,7 +138,7 @@ qx.Class.define("osparc.component.form.json.JsonSchemaForm", {
131138        // Arrays allow to create new items with a button 
132139        const  arrayContainer  =  this . __expandArray ( schema ,  data ,  depth ) ; 
133140        container . add ( arrayContainer ) ; 
134-         const  addButton  =  new  qx . ui . form . Button ( `Add ${ objectPath . get ( schema ,  "items.title" ,  key ) }  ` ,  "@FontAwesome5Solid/plus-circle/14" ) ; 
141+         const  addButton  =  new  qx . ui . form . Button ( `Add ${ objectPath . get ( schema ,  "items.title" ,  schema . title   ||   key ) }  ` ,  "@FontAwesome5Solid/plus-circle/14" ) ; 
135142        addButton . addListener ( "execute" ,  ( )  =>  { 
136143          // key = -1 for an array item. we let JsonSchemaFormArray manage the array keys 
137144          arrayContainer . add ( this . __expand ( - 1 ,  schema . items ,  null ,  depth + 1 ) ) ; 
@@ -141,7 +148,8 @@ qx.Class.define("osparc.component.form.json.JsonSchemaForm", {
141148        // Leaf 
142149        const  input  =  container . addInput ( validation ,  this . __validationManager ) ; 
143150        if  ( data )  { 
144-           input . setValue ( data ) ; 
151+           const  isNumber  =  [ "number" ,  "integer" ] . includes ( schema . type ) ; 
152+           input . setValue ( isNumber  ? String ( data )  : data ) ; 
145153        } 
146154        this . __inputItems . push ( container ) ; 
147155      } 
@@ -178,17 +186,24 @@ qx.Class.define("osparc.component.form.json.JsonSchemaForm", {
178186      }  else  { 
179187        container . setLayout ( new  qx . ui . layout . VBox ( ) ) ; 
180188      } 
181-       Object . entries ( schema . properties ) . forEach ( ( [ key ,  value ] )  =>  container . add ( this . __expand ( key ,  value ,  data  ? data [ key ]  : data ,  depth + 1 ,  { 
182-         required : schema . required  &&  schema . required . includes ( key ) 
183-       } ) ) ) ; 
189+       Object . entries ( schema . properties ) . forEach ( ( [ key ,  value ] ,  index )  =>  { 
190+         const  allProps  =  Object . values ( schema . properties ) ; 
191+         const  nextProp  =  index  <  allProps . length  -  1  ? allProps [ index + 1 ]  : null ; 
192+         container . add ( this . __expand ( key ,  value ,  data  ? data [ key ]  : data ,  depth + 1 ,  { 
193+           required : schema . required  &&  schema . required . includes ( key ) 
194+         } ) ,  { 
195+           lineBreak : nextProp  &&  nextProp . type  ===  "array"  ||  value . type  ===  "array" , 
196+           stretch : value . type  ===  "array" 
197+         } ) ; 
198+       } ) ; 
184199      return  container ; 
185200    } , 
186201    /** 
187202     * Uses objectPath library to construct a JS object with the values from the inputs. 
188203     */ 
189-     toObject : function ( )  { 
204+     toObject : function ( schema )  { 
190205      const  obj  =  { 
191-         json : { } 
206+         json : schema . type   ===   "array"  ?  [ ]  :  { } 
192207      } ; 
193208      const  inputMap  =  { } ; 
194209      // Retrieve paths 
@@ -204,6 +219,7 @@ qx.Class.define("osparc.component.form.json.JsonSchemaForm", {
204219      // Construct object 
205220      Object . entries ( inputMap ) . forEach ( ( [ path ,  item ] )  =>  { 
206221        const  input  =  item . getInput ( ) ; 
222+         const  type  =  item . getType ( ) ; 
207223        if  ( input  instanceof  osparc . ui . form . FileInput )  { 
208224          obj . files  =  obj . files  ||  [ ] ; 
209225          if  ( input . getFile ( ) )  { 
@@ -212,7 +228,8 @@ qx.Class.define("osparc.component.form.json.JsonSchemaForm", {
212228        } 
213229        const  value  =  input . getValue ( ) ; 
214230        if  ( typeof  value  !==  "undefined"  &&  value  !==  null )  { 
215-           objectPath . set ( obj . json ,  path ,  input . getValue ( ) ) ; 
231+           const  isNumber  =  [ "number" ,  "integer" ] . includes ( type ) ; 
232+           objectPath . set ( obj . json ,  path ,  isNumber  ? Number ( input . getValue ( ) )  : input . getValue ( ) ) ; 
216233        } 
217234      } ) ; 
218235      return  obj ; 
@@ -248,6 +265,30 @@ qx.Class.define("osparc.component.form.json.JsonSchemaForm", {
248265        } 
249266      } ) ; 
250267      return  this . __validationManager . validate ( ) ; 
268+     } , 
269+     setSchema : function ( schema )  { 
270+       if  ( this . __validate ( schema . $schema ,  schema ) )  { 
271+         // If schema is valid 
272+         this . __schema  =  schema ; 
273+         if  ( this . __data  &&  ! this . __validate ( this . __schema ,  this . __data ) )  { 
274+           // Data is invalid 
275+           this . __data  =  null ; 
276+         } 
277+       }  else  { 
278+         this . __schema  =  null ; 
279+       } 
280+       this . __render ( this . __schema ) ; 
281+     } , 
282+     setData : function ( data )  { 
283+       if  ( data  &&  this . __validate ( this . __schema ,  data ) )  { 
284+         // Data is valid 
285+         this . __data  =  data ; 
286+         this . __render ( this . __schema ) ; 
287+         return ; 
288+       } 
289+       if  ( this . __validate ( this . __schema ,  this . __data ) )  { 
290+         this . __render ( this . __schema ) ; 
291+       } 
251292    } 
252293  } 
253294} ) ; 
0 commit comments