menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

JSONForms

JSON Forms is a JSON Schema based approach for creating forms and comes with support for React, Angular and Vue. Support here is free, but might involve some delay in the replies based on our current workload for paying customers. We also offer PROFESSIONAL SUPPORT packages to get you started quickly with JSON Forms and to help you with any questions and technical difficulties for JSON Forms with guaranteed response time and in-depth technical solutions. For details please see our web page linked below.

Channels
Team

Ability to add/remove optional properties

October 24, 2019 at 1:10pm

Ability to add/remove optional properties

October 24, 2019 at 1:10pm
Hello, I’m using JsonForms in my project and it’s working very well ! But today I need to integrate a new json schema with a lot of optional properties within an object (>30). I’m using MaterialUI renderers and an uischema of type “Control” to generate the form for this object. What I get is a form with an input for each property (more than 30 input). I would like to be able to display only required or non-empty fields of my object, and to add/remove optional fields when needed (with a property selection dropdown, for instance). I haven’t be able to achieve this with a custom renderer or custom control. Is there any way to achieve this ?

October 24, 2019 at 1:20pm
Hi . Thanks for your positive feedback ;)
The object control is basically nothing more than a shortcut. It just takes all its properties and adds them to a layout. This is useful for prototyping and small objects but is just not flexible enough for larger objects or more complex use cases, as you noticed ;)
I would like to suggest to create your ui schema manually. For example instead of
type: 'Control',
scope: '#/properties/myobject'
you could use
type: 'VerticalLayout',
elements: [
{
type: 'Control',
scope: '#/properties/myobject/properties/name'
},
{
type: 'Control',
scope: '#/properties/myobject/properties/age'
}
...
This way you will have more control about the layout of your form.
Edited
Depending on your use case you could hide/show or enable/disable each control with our built-in rule support. If these are not expressive enough you will need to implement your own ui schema generation. This ui schema can then be used for example by dispatching an action, e.g. Actions.setUischema(uischema) or actually implementing an own custom control for object and using it there instead of the default generated one.

October 25, 2019 at 11:16am
Thanks for your answer. Starting from your example, I implemented a custom layout renderer (following the tutorial from the official website). From there, I can easily control what uischema.element to display or hide, according to selected properties in a dropdown.I can also automatically display non-empty fields by resolving my data against each ui element scope. My class looks like the following :
class OptionalLayoutRenderer extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedProperties: [] // Control what properties "Controls" are visible
}
}
componentDidMount() {
for(element of this.props.uischema.elements) //Initally, display automatically non-empty properties
{
Resolve.data(this.props.data, toPath(element.scope))
//+ if non-empty add element to selectedProperties and update state
}
}
handleSelectProperty = (property) => {
//Add or remove property from selectedProperties and update state
}
render() {
return (
<div>
<MyDropDown onClick={this.handleSelectProperty} ... />
this.state.selectedProperties.map(element => <MaterialLayoutRenderer elements={[element]} .../>);
</div>
);
}
}
export default withJsonFormsLayoutProps(OptionalLayoutRenderer);
export const OptionalLayoutTester= rankWith(1000, uiTypeIs("OptionaLayout"));
The only thing I haven't been able to achieve with this approach is to modify the data : my purpose would be to remove a property from my data when a property is unselected from the dropdown (in handleSelectProperty). The props handleChange from Control Renderers does not seems to be available in my Layout Renderer. Is there a way to improve this class to reach my goal ?
The data lives in the context / redux state. We have an update action with which you can modify the data. In controls you get a dispatch-update injected (handleChange) but for layouts you'll need to do it yourself. You can access dispatch (and build your own handleChange) by building your own version of withJsonFormsLayoutProps.
Edited
As you suggested, I implemented my own withJsonFormsLayoutProps to inject the handleChange prop to my renderer. Now I can modify my data from my class. Works like a charm ! Thanks for your support !
like-fill
1