# Ability to add/remove optional properties

**URL:** <https://jsonforms.discourse.group/t/ability-to-add-remove-optional-properties/125>\
**Category:** General\
**Created:** [October 24, 2019, 1:10pm UTC](https://jsonforms.discourse.group/t/ability-to-add-remove-optional-properties/125 "2019-10-24T13:10:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![discobot](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/discobot/32/3_2.png) [@discobot](https://jsonforms.discourse.group/u/discobot)\
**Post date:** [October 24, 2019, 1:10pm UTC](https://jsonforms.discourse.group/t/ability-to-add-remove-optional-properties/125/1 "2019-10-24T13:10:52Z")

</div>

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 ?

_[[original thread](https://spectrum.chat/jsonforms/general/ability-to-addremove-optional-properties~c2b0c565-7b5d-45c5-b21a-07e2a2ab13c4) by DuncanTls]_

---

<div class="post-metadata">

**Author:** ![sdirix](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/sdirix/32/1073_2.png) [@sdirix](https://jsonforms.discourse.group/u/sdirix)\
**Post date:** [October 24, 2019, 1:20pm UTC](https://jsonforms.discourse.group/t/ability-to-add-remove-optional-properties/125/2 "2019-10-24T13:20:09Z")

</div>

Hi @duncantls. 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

```auto
type: 'Control',
scope: '#/properties/myobject'

```

you could use

```auto
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.

---

<div class="post-metadata">

**Author:** ![sdirix](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/sdirix/32/1073_2.png) [@sdirix](https://jsonforms.discourse.group/u/sdirix)\
**Post date:** [October 24, 2019, 2:06pm UTC](https://jsonforms.discourse.group/t/ability-to-add-remove-optional-properties/125/3 "2019-10-24T14:06:01Z")

</div>

Depending on your use case you could hide/show or enable/disable each control with our built-in [rule support](https://jsonforms.io/docs/uischema/rules). 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.

---

<div class="post-metadata">

**Author:** ![discobot](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/discobot/32/3_2.png) [@discobot](https://jsonforms.discourse.group/u/discobot)\
**Post date:** [October 25, 2019, 11:16am UTC](https://jsonforms.discourse.group/t/ability-to-add-remove-optional-properties/125/4 "2019-10-25T11:16:18Z")

</div>

_[DuncanTls]_

Thanks for your answer. Starting from your example, I implemented a custom layout renderer (following the [tutorial](https://jsonforms.io/docs/custom-layouts) 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 :

```auto
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](https://jsonforms.io/docs/custom-renderers) does not seems to be available in my Layout Renderer. Is there a way to improve this class to reach my goal ?

---

<div class="post-metadata">

**Author:** ![sdirix](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/sdirix/32/1073_2.png) [@sdirix](https://jsonforms.discourse.group/u/sdirix)\
**Post date:** [October 25, 2019, 2:29pm UTC](https://jsonforms.discourse.group/t/ability-to-add-remove-optional-properties/125/5 "2019-10-25T14:29:19Z")

</div>

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`.

---

<div class="post-metadata">

**Author:** ![discobot](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/discobot/32/3_2.png) [@discobot](https://jsonforms.discourse.group/u/discobot)\
**Post date:** [October 25, 2019, 4:15pm UTC](https://jsonforms.discourse.group/t/ability-to-add-remove-optional-properties/125/6 "2019-10-25T16:15:42Z")

</div>

_[DuncanTls]_

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 !
