Relative Scope for Groups

I’m investigating JSONForms 3.x for use on a pretty large project, and one of the things we’d like to use it for is layout reuse. I understand refs need to be resolved ourselves etc, that’s all fine.

One thing that would be useful is having the ability in the Groups to define a top level scope, and then in the elements have their scope relative to the group.

So let’s say I have a Billing Address and a Shipping Address that both refer to the same $def. In our code we would take the common Address UI Schema and build a complete UI schema for the layout. Unless I missed something, I believe all elements in the groups need need to be full paths, ie:

"scope": "#/properties/shipping_address/properties/street_address"
"scope": "#/properties/billing_address/properties/street_address"
etc

It would be awesome if we could define a scope for a group/layout that would join with the scope of the elements so that the inner content of the group/layout would not need to be manipulated. ie:

     {
            "type": "Group",
            "label": "Billing Address",
            "scope": "#/properties/billing_address",
            "elements": [
                {
                    "type": "Control",
                    "scope": "properties/street_address",
                    "label": "Street Address"
                },
                {
                    "type": "HorizontalLayout",
                    "elements": [
                        {
                            "type": "Control",
                            "scope": "properties/city",
                            "label": "City"
                        },
                        {
                            "type": "Control",
                            "scope": "properties/state",
                            "label": "State"
                        }
                    ]
                }
            ]
     },
     {
            "type": "Group",
            "label": "Street Address",
            "scope": "#/properties/shipping_address",
            "elements": [
                <this would be exactly the same as above>
            ]
        },

I did not see anything like this in the documentation, I tried out a few variations of this and didn’t have any success. If there’s a way to do this, or get it added to the roadmap that would be awesome.

Thanks!

Hi @FBNitro,

Thanks for the post! I think your suggestion definitely makes sense and I can see it being useful.

Out of curiosity what is your main motivation? If I understand correctly you would like to have this feature to share UI Schema fragments?

Currently we support this sort of scoping via the object renderer. When you point a Control to a type: 'object', by default the object renderer is invoked. For the object renderer you can define a UI Schema options detail UI Schema, which is scoped against this object instead of root, e.g.

{
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string"
        },
        "mail": {
          "type": "string"
        }
      }
    }
  }
}
{
  "type":"VerticalLayout",
  "elements":[
    {
      "type":"Control",
      "scope":"#/properties/user",
      "options":{
        "detail":{
          "type":"HorizontalLayout",
          "elements":[
            {
              "type":"Control",
              "scope":"#/properties/name"
            },
            {
              "type":"Control",
              "scope":"#/properties/mail"
            }
          ]
        }
      }
    }
  ]
}

Instead of using the options.detail you could also use the uischemas registry which is a prop on the root JSON Forms component. This way your UI Schemas could be more generic, but of course it’s less explicit. uischemas works tester-based, very similar to the renderers registry.


If you instead prefer the approach you outlined here then you can accomplish this rather easily with a custom group renderer. The group renderer can behave similar to the existing one (you could probably even reuse the existing one) but additionally scopes down the JSON Schema, simply by handing over the sub schema instead of the whole schema to the child renderers.

Note however that you will still need to use #/ scopes then. If you prefer the relative scopes of your example then you need custom renderers for all these elements as JSON Forms doesn’t support that out of the box. Again you can reuse all existing renderers but you need to adapt their bindings.

If you like to see some of this functionality within JSON Forms please open an issue against the JSON Forms repository. Please state why the current object oriented approach does not work for you and what exactly you would like to see.

However to be frank this will be prioritized rather low unless on of our paying customers prioritizes the feature or there is a well implemented community contribution.