From e8a7e450fcffe189572371b0ab2f9e01d2a739eb Mon Sep 17 00:00:00 2001 From: Ahmet Tanakol Date: Wed, 23 May 2018 13:56:09 +0200 Subject: [PATCH 1/2] render null if no field is matched with given schema --- packages/core/src/util/renderer.ts | 5 +- .../src/controls/MaterialInputControl.tsx | 42 +++++---- .../renderers/MaterialInputControl.test.tsx | 33 ++++++- .../vanilla/src/controls/InputControl.tsx | 49 +++++----- .../test/renderers/InputControl.test.tsx | 89 +++++++++++++++---- 5 files changed, 157 insertions(+), 61 deletions(-) diff --git a/packages/core/src/util/renderer.ts b/packages/core/src/util/renderer.ts index fcf1a7c4e..bbbb73c53 100644 --- a/packages/core/src/util/renderer.ts +++ b/packages/core/src/util/renderer.ts @@ -133,7 +133,7 @@ export interface RendererProps extends StatePropsOfRenderer { } * State-based props of a Control */ export interface StatePropsOfControl extends StatePropsOfScopedRenderer { - + fields?: { tester: RankedTester, field: any }[]; /** * Any validation errors that are caused by the data to be rendered. */ @@ -337,7 +337,8 @@ export const mapStateToControlProps = (state, ownProps): StatePropsOfControl => scopedSchema: resolvedSchema, uischema: ownProps.uischema, schema: ownProps.schema, - config + config, + fields: state.jsonforms.fields }; }; diff --git a/packages/material/src/controls/MaterialInputControl.tsx b/packages/material/src/controls/MaterialInputControl.tsx index f2af8c375..8d557a03f 100644 --- a/packages/material/src/controls/MaterialInputControl.tsx +++ b/packages/material/src/controls/MaterialInputControl.tsx @@ -23,6 +23,7 @@ THE SOFTWARE. */ import * as React from 'react'; +import * as _ from 'lodash'; import { computeLabel, ControlProps, @@ -32,6 +33,7 @@ import { isDescriptionHidden, isPlainLabel, mapStateToControlProps, + NOT_APPLICABLE, RankedTester, rankWith } from '@jsonforms/core'; @@ -52,7 +54,8 @@ export class MaterialInputControl extends Control { visible, required, parentPath, - config + config, + fields } = this.props; const isValid = errors.length === 0; const trim = config.trim; @@ -69,23 +72,28 @@ export class MaterialInputControl extends Control { }; const showDescription = !isDescriptionHidden(visible, description, this.state.isFocused); + const field = _.maxBy(fields, r => r.tester(uischema, schema)); + if (field === undefined || field.tester(uischema, schema) === NOT_APPLICABLE) { + return null; + } else { - return ( - - - {computeLabel(isPlainLabel(label) ? label : label.default, required)} - - - - {!isValid ? formatErrorMessage(errors) : showDescription ? description : null} - - - ); + return ( + + + {computeLabel(isPlainLabel(label) ? label : label.default, required)} + + + + {!isValid ? formatErrorMessage(errors) : showDescription ? description : null} + + + ); + } } } export const materialInputControlTester: RankedTester = rankWith(1, isControl); diff --git a/packages/material/test/renderers/MaterialInputControl.test.tsx b/packages/material/test/renderers/MaterialInputControl.test.tsx index efd047a3e..156f96461 100644 --- a/packages/material/test/renderers/MaterialInputControl.test.tsx +++ b/packages/material/test/renderers/MaterialInputControl.test.tsx @@ -379,13 +379,13 @@ describe('Material input control', () => { const jsonSchema = { type: 'object', properties: { - password: { type: 'string' } + password: {type: 'string'} } }; const control = { type: 'Control', scope: '#/properties/password', - options: { format: 'password' } + options: {format: 'password'} }; const store = initJsonFormsStore({}, jsonSchema, control); const tree = TestUtils.renderIntoDocument( @@ -396,4 +396,33 @@ describe('Material input control', () => { const input = TestUtils.findRenderedDOMComponentWithTag(tree, 'input'); expect(input.type).toBe('password'); }); + + it('should render null for undefined input control', () => { + const jsonSchema: JsonSchema = { + type: 'object', + properties: { + expectedValue: { + type: [ + 'string', + 'integer', + 'number', + 'boolean' + ] + } + } + }; + + const control = { + type: 'Control', + scope: '#/properties/expectedValue' + }; + const store = initJsonFormsStore({}, jsonSchema, control); + const tree = TestUtils.renderIntoDocument( + + + + ); + const control = TestUtils.scryRenderedDOMComponentsWithTag(tree, 'div')[0] as HTMLElement; + expect(control).toBe(undefined); + }); }); diff --git a/packages/vanilla/src/controls/InputControl.tsx b/packages/vanilla/src/controls/InputControl.tsx index 69ebbd70e..0741bb26e 100644 --- a/packages/vanilla/src/controls/InputControl.tsx +++ b/packages/vanilla/src/controls/InputControl.tsx @@ -1,19 +1,19 @@ /* The MIT License - + Copyright (c) 2018 EclipseSource Munich https://github.com/eclipsesource/jsonforms - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -31,12 +31,14 @@ import { isDescriptionHidden, isPlainLabel, mapStateToControlProps, + NOT_APPLICABLE, RankedTester, rankWith, } from '@jsonforms/core'; import { connectToJsonForms, Control, DispatchField } from '@jsonforms/react'; import { VanillaControlProps } from '../index'; import { addVanillaControlProps } from '../util'; +import * as _ from 'lodash'; export class InputControl extends Control { render() { @@ -50,30 +52,35 @@ export class InputControl extends Control { schema, visible, required, - parentPath + parentPath, + fields } = this.props; const isValid = errors.length === 0; const divClassNames = `validation ${isValid ? classNames.description : 'validation_error'}`; const showDescription = !isDescriptionHidden(visible, description, this.state.isFocused); const labelText = isPlainLabel(label) ? label : label.default; - - return ( -