I'm trying to create Side Menu for nested form ( the nested form should show as subMenu)

Issue:
I’m working on creating a side navigation for a nested form, where the nested forms will be
displayed as a submenu in the sidebar. (The form opens on the right side and navigation will be from the left menu)

Requesting assistance from the community experts for guidance on implementing a side navigation bar with nested forms displayed as submenus in the sidebar.

@sdirix

Details :
Schema: { "type": "object", "definitions": { "InspectionReport": { - Pastebin.com
UiSchema: { "type": "Categorization", "elements": [ { "typ - Pastebin.com

Required: Left vertical navigation menu:

  • Inspection Report:
  •     -Property:
    
  •          - Structure:
    
  •               - Finished Spaces
    
  •                    - Levels
    

If you have the schemas under control then I would typically not implement the navigation as a JSON Forms renderer but use JSON Forms inside your component, i.e. implement a NavigationForms component in which you handle the navigation on your own and use JSON Forms to render the content forms.

If you prefer rendering it within JSON Forms then you could for example use a custom categorization renderers, as hinted at in your UI Schema example.

In fact the categorization renderer of React Vanilla does exactly that: It renders a side bar which can be switched.

@sdirix how to handle the custom navigation with jsonForm. e.g I have created a navigation form when users click the menu item, then need to show reference: form against them.
I am trying to do it this way (but not working ), please correct the right direction, and if you have an example please share.

const menuItem =[
    {
        label: 'Inspection Report',
        value: '#/properties/rating',
        scope:'#/properties/rating',
    },
    {
        label: 'Second Report',
        value: 'ref:#/properties/sdasdsad',
    }
]

const Menu = ({ text, path, onClick }: ListProps) => {

  return (
    <div id='#/properties/menu' style={{ display: 'flex', alignItems:'center' ,justifyContent:'between' }}>
            <List>
                {
                    menuItem.map((item, index)=>(
                        <ListItemButton key={item.label} onClick={()=>onClick(item.scope)}>
                           <ListItemText primary={item.label} />
                        </ListItemButton>
                    ))
                }
            </List>
            <div> 
                {/* form display section */}
            </div>
    </div>

   
  );

};

export default Menu;```

I would like to suggest that in the {/* form display section */} you just render JsonForms with the schema, data and optionally uischema associated with the selected entry of the navigation. Is that possible for you?

Otherwise here is the code of our React Vanilla categorization renderer I showed above.

I am also facing same type of issue, there is any e.g to show nested navigation as left menu and on the click of every nested nav, it will display the data on the right side of the menu. If there is any way to resolve it (please share the code).

Blockquote
Details:
schema: {
“type”: “object”,
“definitions”: {
“InspectionReport”: {
“properties”: {
“property”: {
“$ref”: “#/definitions/sgt.integration.propertydata.v1.Property”,
“additionalProperties”: true,
“type”: “object”
},
“ancillary”: {
“$ref”: “#/definitions/sgt.integration.propertydata.v1.Ancillary”,
“additionalProperties”: true
},
“case_file_id”: {
“type”: “string”
},

        },
        "additionalProperties": true,
        "type": "object",
        "title": "Inspection Report"
    },

“sgt.integration.propertydata.v1.Address”: {
“properties”: {
“street_address”: {
“type”: “string”
},
“unit_number”: {
“type”: “string”
},
“city”: {
“type”: “string”
},
“state”: {
“type”: “string”
},
“postal_code”: {
“type”: “string”
}
},
“additionalProperties”: true,
“type”: “object”,
“title”: “Address”
},
“sgt.integration.propertydata.v1.Property”: {
“properties”: {
“property_occupied”: {
“type”: “boolean”
},
“address”: {
“$ref”: “#/definitions/sgt.integration.propertydata.v1.Address”,
“additionalProperties”: true
},
“structures”: {
“items”: {
“$ref”: “#/definitions/sgt.integration.propertydata.v1.Structures”
},
“type”: “array”
},
}
}
}

uischema: {
“type”: “Categorization”,
“elements”: [
{
“type”: “Category”,
“label”: “Inspection Report”,
“elements”: [
{
“type”: “Control”,
“scope”: “#/properties/InspectionReport”
},
{
“type”: “Categorization”,
“elements”: [
{
“type”: “Category”,
“label”: “Property”,
“elements”: [
{
“type”: “Control”,
“scope”: “#/properties/InspectionReport/properties/property”
},
{
“type”: “Categorization”,
“elements”: [
{
“type”: “Category”,
“label”: “Address”,
“elements”: [
{
“type”: “Control”,
“scope”: “#/properties/InspectionReport/properties/property/properties/address”
}
]
}]},
{
“type”: “Category”,
“label”: “Anxillary”,
“elements”: [
{
“type”: “Control”,
“scope”: “#/properties/InspectionReport/properties/ancillary”
}]}]}]}

The ‘Menu’ component is a custom component used for rendering in JSONForms. To use it, export it with the ‘JsonForms’ control properties like this: export default withJsonFormsControlProps(MenuControl);. The main challenge is designing the ‘schema.json’ and ‘UISchema.json’ to meet the above requirements. I would greatly appreciate your assistance with this. @sdirix

Hi @shujaat.dev,

As written above, if the schema and UI Schema are in your hands then I would probably not go for a custom renderer solution, but rather write a component which renders a navigation and then invokes JSON Forms for each shown “detail”.

If this must be located within a single JSON Schema, then this can easily be done by having a base object whose properties then each define self-contained objects for the details. Then you just dispatch the subschemas to JSON Forms instead of the whole JSON Schema.

Otherwise if you want to go the custom renderers route, then either using a custom Categorization renderer or a custom object renderer makes the most sense. If you are able to define the JSON Schema yourself then I would go for the object-approach described above combined with a custom object renderer for the navigation. Then you don’t need to additionally maintain the UI Schema. The UI Schema is best for situations where you can’t control the JSON Schema but want to influence the layout.

Could you please provide an example implementation? I have tried but am unable to implement your solution

@shujaat.dev, If you can make a branch available (e.g. a fork of the React seed with your custom renderer) where you are currently struggling I could take a look.

Sure thank you, I will create a branch

@sdirix, could you please take a look at this Repo, I have added a problem.md file that describes the issue where I need your guidance and help. Highly appreciate your time and assistance.

Hi @shujaat.dev,

Thanks for the repo, I plan to take a look and come back to you within a week.

thanks, highly appreciated

I had a look over the code:

  • Application logic should not be encoded in the schema. The JSON Schema should describe the overall data structure which you later want to process and for example hand over to some backend. In your case I guess this should be the Inspection Report.
    • In your case you should think about whether you want to split your JSON Schema into multiple ones. Each of them referring to a “standalone” part of the form
  • Rendering the menu outside of JSON Forms makes sense, however it should not be partially based on the UI Schema. Again, ideally the UI Schema should just be form related and not directly contain any business logic outside of JSON Forms.
  • I would have expected that if a single JSON Schema is used, that it’s clearly consisting of separate objects. Then you could hand in a separate schema and uischema whenever a link is clicked.
    • However it looks to me that you actually have one large object with many deeply nested properties, and for these you want to offer a navigation. Suggestion: Just render the whole schema as it is. Every control has a unique id. So you could just scroll to these controls when they are clicked in the separately rendered navigation part. The navigation part is a custom component outside of JSON Forms and could take in the schema and from that predict the ids.
      This could be streamlined by for example adding a custom object renderer which renders a navigatable element and registers itself outside of JSON Forms in a custom context. Then your navigation element could consume the same context and pick up all registered objects. Then the navigation would only offer things which are currently actually rendered.

Note that properties with dots are currently partially broken in JSON Forms, so for now I would recommend to not use dots in the properties. We are working on a fix.