diff --git a/src/program/ProgramInit.js b/src/program/ProgramInit.js index e363c9f..d4db00f 100644 --- a/src/program/ProgramInit.js +++ b/src/program/ProgramInit.js @@ -55,15 +55,49 @@ module.exports = Class( 'ProgramInit', 'public init'( program, doc_data ) { const defaults = program.defaults || {}; + const data = doc_data || {}; + const groups = program.meta.groups; - // initialize to an array with a single element of the default value - return Promise.resolve( - Object.keys( defaults ).reduce( - ( data, key ) => ( data[ key ] === undefined ) - ? ( data[ key ] = [ defaults[ key ] ], data ) - : data, - doc_data || {} - ) - ); + Object.keys( program.groupExclusiveFields ).forEach( group => + { + let i = program.groupExclusiveFields[ group ].length; + + while ( i-- ) + { + const field = program.groupExclusiveFields[ group ][ i ]; + const default_value = defaults[ field ]; + + if ( !defaults.hasOwnProperty( field )) + { + continue; + } + + // Initialize with existing document data if any + + // If no document data, initialize with default value + if ( data[ field ] === undefined ) + { + data[ field ] = [ default_value ]; + } + + // If min rows on the group is greater than the data + // currently in the bucket, then populate the rest + // of the data with the default data until the + // arrays are the same length + if ( groups.hasOwnProperty( group ) && + data[ field ].length < groups[ group ].min ) + { + let index = data[ field ].length; + + while ( index < groups[ group ].min ) + { + data[ field ][ index ] = default_value; + index++; + } + } + } + }); + + return Promise.resolve( data ); }, } ); diff --git a/src/ui/group/GroupUi.js b/src/ui/group/GroupUi.js index 21824f8..ac506a8 100644 --- a/src/ui/group/GroupUi.js +++ b/src/ui/group/GroupUi.js @@ -791,8 +791,13 @@ module.exports = Class( 'GroupUi' ) : $element; }, - - 'public hideField': function( field, index ) + /** + * Hides the field based on field name and index + * + * @param field + * @param index + */ + 'virtual public hideField': function( field, index ) { if ( this.isFieldVisible( field, index ) === false ) { @@ -813,8 +818,26 @@ module.exports = Class( 'GroupUi' ) .applyStyle( this._naStyler ); }, + /** + * Returns a boolean depending on if there are visible fields + * based off of the visCount + * + * @param index + * @returns {boolean} + */ + 'protected hasVisibleField'( index ) + { + return this._visCount[ index ] > 0 ? true : false; + }, - 'public showField': function( field, index ) + + /** + * Shows the field based on field name and index + * + * @param field + * @param index + */ + 'virtual public showField': function( field, index ) { if ( this.isFieldVisible( field, index ) === true ) { diff --git a/src/ui/group/StackedGroupUi.js b/src/ui/group/StackedGroupUi.js index 0da7145..bf0eb9b 100644 --- a/src/ui/group/StackedGroupUi.js +++ b/src/ui/group/StackedGroupUi.js @@ -100,4 +100,43 @@ module.exports = Class( 'StackedGroupUi' ) return this.__super( index ); }, + + + /** + * Hide the header if there are no visible fields + * + * @param field + * @param index + */ + 'public override hideField'( field, index ) + { + this.__super( field, index ); + + if ( !this.hasVisibleField( index ) ) + { + const header = this._$container.find( 'dl' )[ index ]; + + header.classList.add( 'hidden' ); + } + }, + + + /** + * Show the header if there are visible fields + * + * @param field + * @param index + */ + 'public override showField'( field, index ) + { + this.__super( field, index ); + + if ( this.hasVisibleField( index ) ) + { + const header = this._$container.find( 'dl' )[ index ]; + + header.classList.remove( 'hidden' ); + } + + } } ); diff --git a/test/program/ProgramInitTest.js b/test/program/ProgramInitTest.js index 581a5c4..8d3ee90 100644 --- a/test/program/ProgramInitTest.js +++ b/test/program/ProgramInitTest.js @@ -34,6 +34,12 @@ describe( 'ProgramInit', () => { label: "initializes defaults", defaults: { a: "one", b: "two" }, + meta: { + groups: {} + }, + groupExclusiveFields: { + Something: [ "a", "b" ] + }, doc_data: {}, expected: { a: [ "one" ], @@ -43,18 +49,36 @@ describe( 'ProgramInit', () => { label: "does nothing with no data or defaults", defaults: {}, + meta: { + groups: {} + }, + groupExclusiveFields: {}, doc_data: {}, expected: {}, }, { label: "produces empty object given undefined data", defaults: {}, + meta: { + groups: {} + }, + groupExclusiveFields: {}, doc_data: undefined, expected: {}, }, { label: "keeps existing data with defaults", - defaults: { foo: "init" }, + defaults: { + foo: "init", + bar: "test" + }, + meta: { + groups: {} + }, + groupExclusiveFields: { + Something: [ "foo" ], + SomethingElse: [ "bar" ] + }, doc_data: { bar: [ "baz" ] }, expected: { foo: [ "init" ], @@ -62,22 +86,90 @@ describe( 'ProgramInit', () => }, }, { - label: "keeps existing doc data with no defaults", + label: "keeps existing data with no defaults", defaults: {}, + meta: { + groups: {} + }, + groupExclusiveFields: { + SomethingElse: [ "bar" ] + }, + doc_data: { bar: [ "baz" ] }, + expected: { + bar: [ "baz" ], + }, + }, + { + label: "does not overwrite existing data with defaults", + defaults: { foo: "init" }, + meta: { + groups: {} + }, + groupExclusiveFields: { + Something: [ "foo" ] + }, doc_data: { foo: [ "bar" ] }, expected: { foo: [ "bar" ], }, }, { - label: "does not overwrite existing data with defaults", + label: "does not overwrite existing data with defaults and multiple rows", defaults: { foo: "init" }, - doc_data: { foo: [ "bar" ] }, + meta: { + groups: { + Something: { + min: 3 + } + } + }, + groupExclusiveFields: { + Something: [ "foo" ] + }, + doc_data: { foo: [ "bar", "baz", "test" ] }, expected: { - foo: [ "bar" ], + foo: [ "bar", "baz", "test" ], }, }, - ].forEach( ({ label, doc_data, id, defaults, expected }) => + { + label: "initializes with default bucket data", + defaults: { foo: "init" }, + meta: { + groups: { + Something: { + min: 5 + } + } + }, + groupExclusiveFields: { + Something: [ "foo" ] + }, + doc_data: {}, + expected: { + foo: [ "init", "init", "init", "init", "init" ], + }, + }, + { + label: "fix missing bucket data values", + defaults: { foo: "init" }, + meta: { + groups: { + Something: { + min: 5 + } + } + }, + groupExclusiveFields: { + Something: [ "foo" ] + }, + doc_data: { + foo: [ "1", "2", "3", "4" ], + }, + expected: { + foo: [ "1", "2", "3", "4", "init" ], + }, + }, + ].forEach( ({ label, doc_data, id, defaults, meta, groupExclusiveFields, expected }) => { it( label, () => { @@ -86,6 +178,8 @@ describe( 'ProgramInit', () => const program = { id: "foo", defaults: defaults, + meta: meta, + groupExclusiveFields : groupExclusiveFields }; return expect( sut.init( program, doc_data ) )