Conditional rendering for Array type

We have in JSON Schema property of type array, and inside items for array element we have 100 fields, which are getting rendered as they are coming in Schema file, but what we need is more control over which fields we need to show on UI.

Schema File Content

{
    "type": "object",
    "properties": {
      "interface": {
        "type": "array",
        "items": {
          "description": "The list of named interfaces on the device.",
          "type": "object",
          "properties": {
            "name": {
              "description": "Desc",
              "type": "string",
              "minLength": 1
            },
            "config": {
              "description": "Configurable items at the global, physical interface level",

UISchema

uischema: {
  type: "HorizontalLayout",
  elements: [
    {
      type: "VerticalLayout",
      elements: [
        {
          type: "Control",
          scope: "#/properties/interface/"
        }
      ]
    }
  ]
}

As you can see by just adding one control in UI schema i am able to generate all 100 fields, but i want to show only 10 selected fields on UI and not remaining 90 fields from array.

Are we supporting this scenario, if yes can you please help me in this regards.

Hi @rohan.thakare,

The main way to customize the array rendering is by handing over a detail UI Schema, e.g.

{
  type: "Control",
  scope: "#/properties/interface",
  options: {
    detail: {
      type: "VerticalLayout",
      elements: [
        {
          type: "Control",
          scope: "#/properties/name"
        }
      ]
    }
  }
}

For completeness sake: Alternatively one can use the uischemas registry and register the detail UI Schema there.

Hi Stefan,

Thanks for the response, tried solution provided, but still getting all fields from Array of Objects in UI, is it because for Vue we dont have renderer for Array of Objects ?

Renderer

Do we need to write custom renderer for Array of Objects for Vue to resolve this ?

Thank you.

Hi @rohan.thakare,

So you’re using Vue Vanilla? Note that we also have a fully featured Vue 2 Vuetify renderer set available (which is not yet documented on the website).

The documentation shows that Vue Vanilla supports rendering an Array of objects as a List which is the mechanism I referred to, so I would expect the suggested approach to work for Vue Vanilla.

Can you post the full schema and uischema which doesn’t work for you?

Hi Stefan,

Yes we are using Vue Vanilla, and yes we are getting fields in UI from array of objects, but we need to show only some fields and not all, attaching Schema (Did not get option to attach full schema so posted partial schema from the start) and UI Schema,

So we are expecting is as per UI schema only name field should be shown in array and not others, but we are still getting all fields from array, screenshot added

UI Schema

uischema: {
        type: "Control",
        scope: "#/properties/interface",
        options: {
          detail: {
            type: "VerticalLayout",
            elements: [
              {
                type: "Control",
                scope: "#/properties/name"
              }
            ]
          }
        }
      }

Schema

{
    "type": "object",
    "properties": {
      "interface": {
        "type": "array",
        "items": {
          "description": "The list of named interfaces on the device.",
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "config": {
              "allOf": [
                {
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "enable-switchport": {
                      "type": "string"
                    },
                    "vrf-name": {
                      "type": "string"
                    },
                    "vr-name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "other",
                        "regular1822",
                        "hdh1822",
                        "ddnX25",
                        "rfc877x25",
                        "ethernetCsmacd"
                      ]
                    },
                    "mtu": {
                      "type": "integer"
                    },
                    "dot1ad-ether-type": {
                      "type": "string"
                    },
                    "domain-fastflush-config": {
                      "type": "string"
                    },
                    "protected-port": {
                      "default": "promiscuous",
                      "type": "string",
                      "enum": [
                        "community",
                        "isolated",
                        "promiscuous"
                      ]
                    },
                    "domain-forward-config": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "shutdown": {
                      "type": "string"
                    }
                  }
                }
              ]
            },
            "state": {
              "allOf": [
                {
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "enable-switchport": {
                      "type": "string"
                    },
                    "vrf-name": {
                      "description": "This attribute is used to associates an interface with a VRF",
                      "type": "string"
                    },
                    "vr-name": {
                      "description": "This attribute is used to associates an interface with a VR",
                      "type": "string"
                    },
                    "type": {
                      "description": "The type of the interface.\nWhen an interface entry is created, a server MAY\ninitialize the type leaf with a valid value, e.g., if it\nis possible to derive the type from the name of the\ninterface.",
                      "type": "string",
                      "enum": [
                        "other",
                        "regular1822",
                        "hdh1822",
                        "ddnX25",
                        "rfc877x25",
                        "ethernetCsmacd"
                      ]
                    },
                    "mtu": {
                      "description": "This attribute is used to set mtu value to interface.The size of the\nlargest packet which can be sent/received on the interface, specified\nin octets.  For interfaces that are used for transmitting network\ndatagrams, this is the size of the largest network datagram that can\nbe sent on the interface.",
                      "type": "integer"
                    },
                    "dot1ad-ether-type": {
                      "description": "This attribute is used to configure the ethertype value for the\ninterface in the format 0xhhhh. Currently supported values are 0x8100\n(default) or 0x88a8 or 0x9100 or 0x9200.",
                      "type": "string"
                    },
                    "domain-fastflush-config": {
                      "description": "Attribute to change domain fastflush value",
                      "type": "string"
                    },
                    "protected-port": {
                      "description": "Attribute to change port protectedtype value",
                      "default": "promiscuous",
                      "type": "string",
                      "enum": [
                        "community",
                        "isolated",
                        "promiscuous"
                      ]
                    },
                    "domain-forward-config": {
                      "description": "Attribute to change domain forward value",
                      "type": "string"
                    },
                    "description": {
                      "description": "Use this attribute to set description for the interface",
                      "type": "string"
                    },
                    "shutdown": {
                      "description": "Use this attribute to enable the selected interface.\nThis leaf contains the configured, desired state of the interface.\nThe testing(3) state indicates that no operational packets can be\npassed.\nWhen a managed system initializes, all interfaces start with\nifAdminStatus in the down(2) state.\nAs a result of either explicit management action or per configuration\ninformation retained by the managed system,\nifAdminStatus is then changed to either the up(1) or testing(3)\nstates (or remains in the down(2) state).",
                      "type": "string"
                    },
                    "ifindex": {
                      "description": "System assigned number for each interface. A unique value,\ngreater\nthan zero, for each interface.It is recommended that values are\nassigned contiguously starting from 1.The value for each interface\nsub-layer must remain constant at least from one re-initialization\nof the entity's network management system to the next\nre-initialization.",
                      "type": "integer"
                    },
                    "admin-status": {
                      "description": "The desired state of the interface. It reflects the\nadministrative\nstate as set by enabling or disabling the interface.",
                      "type": "string",
                      "enum": [
                        "up",
                        "down",
                        "testing"
                      ]
                    },
                    "oper-status": {
                      "description": "The current operational state of the interface.  The\ntesting(3) state indicates that no operational packets can\nbe passed.  If admin-status is down(2) then oper-status\nshould be down(2).  If admin-status is changed to up(1)\nthen oper-status should change to up(1) if the interface is\nready to transmit and receive network traffic; it should\nchange to dormant(5) if the interface is waiting for\nexternal actions (such as a serial line waiting for an\nincoming connection); it should remain in the down(2) state\nif and only if there is a fault that prevents it from going\nto the up(1) state; it should remain in the notPresent(6)\nstate if the interface has missing (typically, hardware)\ncomponents.",
                      "type": "string",
                      "enum": [
                        "up",
                        "down",
                        "testing",
                        "unknown",
                        "dormant",
                        "notPresent",
                        "lowerLayerDown"
                      ]
                    },
                    "last-change": {
                      "description": "The value of sysUpTime at the time the interface entered\nits current operational state.If the current state was\nentered prior to the last re-initialization of the local\nnetwork management subsystem then this object contains a\nzero value",
                      "type": "integer"
                    },
                    "logical": {
                      "description": "When set to true, the interface is a logical interface\nwhich does not have an associated physical port or channel on the\nsystem",
                      "type": "boolean"
                    },

Hi! I just checked the code. The Vue Vanilla Array binding sadly skips the detail UI Schema option. This is a bug. I created a new issue for this: #1900. Once this is fixed the issue should be gone.

You should be able to use the uischemas registry to get your detailed schema in. Alternatively you could copy and register the array renderer with a fixed binding.

Hi Stefan,

Thank you for the update, can you please let us know on ETA for fixing above issue, meanwhile will work on the workaround you provided.

I can’t give any concrete ETAs as this depends on our current workload and the priorities of our paying customers. In general we try to fix bugs, especially straightforward ones, as soon as possible. I’l try to get this in for JSON Forms 3.0 but I can’t make any promises. Of course we always welcome contributions.