How to get data to custom Layout & custom control

Hi JSONForms Team,

Thank very much for having this channel and such a nice library.

I am trying to create custom Layout Renderer (MyGroupLayoutControl) using List and used it with custom renderer. I am using List control from UI5-WebComponent-react library. @ui5/webcomponents-react - npm .
I am able to get the fields from UI Schema using my custom control but I cannot get the Data to show up on the UI next to field, eventhough in my layoutProp I see its being passed.

/**********MyGroupLayoutControl.js *****************/
import { MaterialLayoutRenderer, MaterialControlRenderer} from ‘@jsonforms/material-renderers’;

//import { VanillaLayoutRenderer } from ‘@jsonforms/vanilla-renderers’;

import React from ‘react’;

import { withJsonFormsLayoutProps, withJsonFormsArrayControlProps, withJsonFormsControlProps } from ‘@jsonforms/react’;

import { CustomListItem } from “@ui5/webcomponents-react/lib/CustomListItem”;

import { List } from “@ui5/webcomponents-react/lib/List”;

import styles from “…/App.css”;

const offerData = {

OFFER: {

items: [

  {

    offerLetterId: 123,

    offerSentDate: "2012-11-09",

    sentBy: "Lorna Okamoto",

    senderUserId: "lokamoto1",

    lastUpdatedDate: "2020-12-02",

    sendMode: "eSignOffer",

    comments: "sample text",

    subject: "Offer-Executive",

    offerLetterSecKey: "uniquely generated key alphaneumeric key",

    candResponseDate: "2020-12-02",

    candResponseComments: "sample text",

    status: "pending",

    cancelOffer: true,

    OfferEsignDetail: "https://odata/V4/recruiting/ApplicationManagement.svc/v1/OfferLetters(123)"

  },

  {

    offerLetterId: 125,

    offerSentDate: "2020-10-09",

    sentBy: "Carla Grant",

    senderUserId: "cgrant",

    lastUpdatedDate: "2020-12-02",

    sendMode: "eSignOffer",

    subject: "Offer-Engineering Manager",

    certificate: "View Certificate",

    offerLetterSecKey: "uniquely generated key alphaneumeric key",

    candResponseDate: "2020-12-02",

    candResponseComments: "sample text",

    status: "pending",

    cancelOffer: false,

    OfferEsignDetail: "https://odata/V4/recruiting/ApplicationManagement.svc/v1/OfferLetters(123)"

  }

]

}

};

const MyGroupLayoutControl = (props) => {

const { data, uischema, schema, path, enabled, cells, visible, renderers } = props;

const layoutProps = {

elements: uischema.options.detail.elements,

schema: schema,

path: path,

direction: 'column',

visible: visible,

enabled: enabled,

cells: cells,

uischema: uischema,

renderers: renderers,

data: data

};

function getSectionItemId(key) {

return "sectionItems_" + key;

}

const renderListItems = (list) => {

if (list) {

  return list.map((key) => {

    return (

      <CustomListItem

        id={getSectionItemId(key)}

        key={getSectionItemId(key)}

        data-option-id={key}

        data-testid={getSectionItemId(key)}

        aria-label={getSectionItemId(key)}

        className={styles.customListItem}

      >

        <div>

        <MaterialLayoutRenderer {...layoutProps} /> 

        </div>

      </CustomListItem>

    );

  });

}

return "";

};

return (

<>

  <List data-testid="sectionList">

  {renderListItems(offerData.OFFER.items)} 

  </List>

</>

);

};

export default withJsonFormsArrayControlProps(MyGroupLayoutControl);
Below is my UI Template.
{
“type”: “VerticalLayout”,
“elements”: [
{
“type”: “MyGroup”,
“scope”: “#/properties/OFFER/properties/items”,
“options”: {
“detail”: {
“type”: “VerticalLayout”,
“elements”: [
{
“type”: “Control”,
“scope”: “#/properties/subject”
},
{
“type”: “Control”,
“scope”: “#/properties/offerSentDate”
},
{
“type”: “Control”,
“scope”: “#/properties/sentBy”
},

                    {
                      "type": "Control",
                      "scope": "#/properties/sendMode"
                    },
                    {
                      "type": "Control",
                      "scope": "#/properties/comments"
                    },
                    {
                      "type": "Control",
                      "scope": "#/properties/status"
                    }
                  ]
                       }
              }
            }
          ]
        }

My JSONSchema is as below -
“OFFER”: {

  "type": "object",

  "properties": {

    "items": {

      "type": "array",

      "items": {

        "type": "object",

        "additionalProperties": false,

        "properties": {

          "offerLetterId": {

            "type": "integer",

            "options": {

              "hidden": true

            },

            "readOnly": true,

            "title": ""

          },

          "offerSentDate": {

            "type": "string",

            "format": "date",

            "readOnly": true,

            "title": "Offer Extended On"

          },

          "sentBy": {

            "type": "string",

            "readOnly": true,

            "title": "Author"

          },

          "senderUserId": {

            "type": "string",

            "options": {

              "hidden": true

            },

            "readOnly": true

          },

          "lastUpdatedDate": {

            "type": "string",

            "format": "date",

            "options": {

              "hidden": true

            },

            "readOnly": true

          },

          "sendMode": {

            "type": "string",

            "readOnly": true,

            "title": "Send Mode",

            "fieldType": "link"

          },

          "comments": {

            "type": "string",

            "readOnly": true,

            "title": "Comments"

          },

          "subject": {

            "type": "string",

            "readOnly": true,

            "title": "",

            "fieldType": "link"

          },

          "offerLetterSecKey": {

            "type": "string",

            "options": {

              "hidden": true

            }

          },

          "candResponseDate": {

            "type": "string",

            "format": "date",

            "readOnly": true,

            "title": "Candidate Responded On"

          },

          "candResponseComments": {

            "type": "string",

            "readOnly": true,

            "title": "Candidate Response Comment",

            "options": { "hidden": true }

          },

          "status": {

            "type": "string",

            "readOnly": true,

            "title": ""

          },

          "cancelOffer": {

            "type": "boolean",

            "readOnly": true,

            "fieldType": "button",

            "title": "Cancel Offer"

          },

          "OfferEsignDetail": {

            "type": "string",

            "format": "uri",

            "qt-uri-protocols": ["https"],

            "qt-uri-extensions": [".getesignofferletters()"]

          }

        },

     "required": [],

        "title": "Offer "

      },

      "title": "Offer"

    }

  },

  "required": ["id", "items"],

  "title": "Offers"

}

Please help with resolving this issue.

Regards,
Kushal K

Hi @kkaranjkar,

I’m not exactly sure what you are trying to accomplish. What parts of JSON Forms are you trying to reuse and which parts shall be custom?

Some issues I see:

  • Your custom renderer requests the array control props, but these props are then handed over to the MaterialLayoutRenderer. This probably leads to a mismatch of props.
  • The custom renderer seems to be invoked on #/properties/OFFER/properties/items but only renders a subset of data, i.e. offerData.OFFER.items. Something is not matching here.

Please describe exactly what you are trying to do.

Hi Stefan,
Thanks for your reply and suggestions.
I have created wrapper custom controls - TextControl, InputControl, LinkControl etc. which are working for inbuild layouts. I was having trouble getting custom Layout which shows list (not “ListWithDetails”).

Finally, I did follow the blog example - GitHub - edge33/jsonforms-custom-array-demo: An example of jsonforms with a custom array layout and implemented custom List layout.

I am working on POC and we are evaluating at the organization level whether we can use JSONForm as library with Vanilla react renderer for future UI development. So far we are happy what it could do.

Now, We are evaluating on how we can use JSONForms and achieve responsiveness, accessibility, support for complex objects like (Date (formated), currency, picklist etc) and generating UI without UI Schema with Vanilla renderer.
If you have example of above with Vanilla renderer, please help share .

Regards,
Kushal Karanjkar

Hi @kkaranjkar, great that you managed to solve your problems!

At the moment our React Material renderers are the most polished ones. The React Vanilla renderers are relatively basic, however as you can customize any renderer in JSON Forms you can also implement any responsiveness, accessibility or other feature you’d like to see. Sadly, I don’t have any special Vanilla renderer examples available to me.

Creating a custom UI Schema (generator) is (usually) independent from any specific renderer set. Of course if you have special features only supported by your renderer set your UI Schema generator might want to reflect that.