diff --git a/components/renderers/controls/array/array-renderer.spec.ts b/components/renderers/controls/array/array-renderer.spec.ts index 68580e137..7e1e810eb 100644 --- a/components/renderers/controls/array/array-renderer.spec.ts +++ b/components/renderers/controls/array/array-renderer.spec.ts @@ -84,7 +84,6 @@ describe('Array renderer', () => { let el = $compile('')(scope); scope.$digest(); let fieldSet = angular.element(el[0].getElementsByTagName("fieldset")); - console.log(fieldSet); expect(fieldSet.attr("disabled")).toBeDefined(); })); }); \ No newline at end of file diff --git a/components/renderers/controls/control.html b/components/renderers/controls/control.html index 95c193bc0..2a66ac1d6 100644 --- a/components/renderers/controls/control.html +++ b/components/renderers/controls/control.html @@ -1,6 +1,6 @@
- +
diff --git a/components/renderers/jsonforms-renderers.d.ts b/components/renderers/jsonforms-renderers.d.ts index 6cf58490b..36a4ac344 100644 --- a/components/renderers/jsonforms-renderers.d.ts +++ b/components/renderers/jsonforms-renderers.d.ts @@ -14,10 +14,11 @@ declare module JSONForms { export interface IRenderDescription { type: string + size: number template?: string templateUrl?: string - size: number rule?: IRule; + showLabel?: boolean } export interface IControlRenderDescription extends IRenderDescription { diff --git a/components/renderers/jsonforms-renderers.ts b/components/renderers/jsonforms-renderers.ts index d3411f36a..094d5240d 100644 --- a/components/renderers/jsonforms-renderers.ts +++ b/components/renderers/jsonforms-renderers.ts @@ -60,12 +60,46 @@ module JSONForms { return new ControlRenderDescription(schemaPath, services, element); } - // TODO doc + /** + * This is a helper method typically used by layouts that render their contained children in a horizontal + * fashion. In contrast to {@link renderElements} this function also takes into account whether labels + * of controls should be rendered at all, which might be the case if the UI schema declaration states that + * the label for each control is not to be shown. + * + * @param elements the UI schema children elements to be rendered + * @param renderService the RenderService that is used to render the UI schema elements + * @param services the service registry + * @returns {*[]} an array of RenderDescription objects that describe the UI schema elements to be rendered + */ + static renderElementsHorizontally(elements:IUISchemaElement[], renderService: JSONForms.IRenderService, services:JSONForms.Services):JSONForms.IRenderDescription[] { + + let labelExists = elements.reduce((atLeastOneLabel, element) => { + return atLeastOneLabel || LabelObjectUtil.shouldShowLabel(element.label); + }, false); + + return elements.map(element => { + let renderDesc = renderService.render( + services.get(ServiceId.ScopeProvider).getScope(), + element, + services); + renderDesc.showLabel = labelExists; + return renderDesc; + }); + } + + /** + * This is a helper method typically used by layouts to render their contained children. + * + * @param elements the UI schema children elements to be rendered + * @param renderService the RenderService that is used to render the UI schema elements + * @param services the service registry + * @returns {*[]} an array of RenderDescription objects that describe the UI schema elements to be rendered + */ static renderElements(elements:IUISchemaElement[], renderService: JSONForms.IRenderService, services:JSONForms.Services):JSONForms.IRenderDescription[] { - return elements.map((el) => { + return elements.map(element => { return renderService.render( services.get(ServiceId.ScopeProvider).getScope(), - el, + element, services); }); } @@ -100,11 +134,11 @@ module JSONForms { public size = 100; public alerts: any[] = []; // TODO IAlert type missing public label: string; + public showLabel: boolean; public rule: IRule; public readOnly: boolean; public path: string; public instance: any; - private schema: SchemaElement; private validationService: IValidationService; private pathResolver: IPathResolver; @@ -121,20 +155,18 @@ module JSONForms { this.path = PathUtil.normalize(schemaPath); this.label = this.createLabel(schemaPath, element.label); + // by default labels are shown + this.showLabel = LabelObjectUtil.shouldShowLabel(element.label); this.readOnly = element.readOnly; this.rule = element.rule; this.ruleService.addRuleTrack(this); this.setupModelChangedCallback(); } - private createLabel(schemaPath:string, label?:IWithLabel):string { - var stringBuilder = ""; + private createLabel(schemaPath:string, label: IWithLabel):string { - var labelObject = LabelObjectUtil.getElementLabelObject(label, schemaPath); - - if (labelObject.show) { - stringBuilder += labelObject.text; - } + let labelObject = LabelObjectUtil.getElementLabelObject(label, schemaPath); + let stringBuilder = labelObject.text; if (this.isRequired(schemaPath)) { stringBuilder += "*"; @@ -197,6 +229,20 @@ module JSONForms { } export class LabelObjectUtil { + + public static shouldShowLabel(label: IWithLabel): boolean { + if (label === undefined ) { + return true; + } else if (typeof label === 'boolean') { + return label; + } else if (typeof label === 'string') { + return ( label) != ""; + } else { + let labelObj = label; + return labelObj.hasOwnProperty("show") ? labelObj.show : true; + } + } + public static getElementLabelObject(labelProperty:IWithLabel, schemaPath:string):ILabelObject { if (typeof labelProperty === "boolean") { if (labelProperty) { diff --git a/components/renderers/layouts/horizontal/horizontal-renderer.spec.ts b/components/renderers/layouts/horizontal/horizontal-renderer.spec.ts new file mode 100644 index 000000000..4494767cf --- /dev/null +++ b/components/renderers/layouts/horizontal/horizontal-renderer.spec.ts @@ -0,0 +1,83 @@ +/// + +describe('HorizontalLayout', () => { + + // load all necessary modules and templates + beforeEach(module('jsonforms.form')); + beforeEach(module('jsonforms.renderers.layouts.horizontal')); + beforeEach(module('jsonforms.renderers.controls.string')); + + beforeEach(module('components/form/form.html')); + beforeEach(module('components/renderers/layouts/layout.html')); + beforeEach(module('components/renderers/controls/control.html')); + + it("should take into account if some labels are hidden", inject(($rootScope, $compile) => { + let scope = $rootScope.$new(); + scope.schema = { + "properties": { + "foo": { "type": "string" }, + "bar": { "type": "string" } + } + }; + scope.uiSchema = { + "type": "HorizontalLayout", + "elements": [ + { + "type": "Control", + "label": true, + "scope": { "$ref": "#/properties/foo" } + }, + { + "type": "Control", + "label": false, + "scope": { "$ref": "#/properties/bar" } + } + ] + }; + + scope.data = { "foo": "quux", "bar": "baz" }; + let el = $compile('')(scope); + scope.$digest(); + let labelElements = el.find('label'); + expect(labelElements).toBeDefined(); + // one label is empty + expect(labelElements.length).toEqual(2); + expect(angular.element(labelElements[0]).text()).toEqual("Foo"); + expect(angular.element(labelElements[1]).text()).toEqual(""); + })); + + it("should take into account if all labels are hidden", inject(($rootScope, $compile) => { + let scope = $rootScope.$new(); + scope.schema = { + "properties": { + "foo": { "type": "string" }, + "bar": { "type": "string" } + } + }; + scope.uiSchema = { + "type": "HorizontalLayout", + "elements": [ + { + "type": "Control", + "label": { + show: false + }, + "scope": { "$ref": "#/properties/foo" } + }, + { + "type": "Control", + "label": { + show: false + }, + "scope": { "$ref": "#/properties/bar" } + } + ] + }; + + scope.data = { "foo": "quux", "bar": "baz" }; + let el = $compile('')(scope); + scope.$digest(); + let labelElements = el.find('label'); + expect(labelElements.length).toBe(0); + })); +}); \ No newline at end of file diff --git a/components/renderers/layouts/horizontal/horizontal-renderer.ts b/components/renderers/layouts/horizontal/horizontal-renderer.ts index 680719b80..b6b2ff62e 100644 --- a/components/renderers/layouts/horizontal/horizontal-renderer.ts +++ b/components/renderers/layouts/horizontal/horizontal-renderer.ts @@ -10,7 +10,7 @@ class HorizontalRenderer implements JSONForms.IRenderer { var maxSize = 100; - var renderedElements = JSONForms.RenderDescriptionFactory.renderElements( + var renderedElements = JSONForms.RenderDescriptionFactory.renderElementsHorizontally( element.elements, this.renderService, services); var size = renderedElements.length; var individualSize = Math.floor(maxSize / size);