# Rendering Images Dynamically

**URL:** <https://jsonforms.discourse.group/t/rendering-images-dynamically/2588>\
**Category:** General\
**Created:** [February 4, 2025, 2:00pm UTC](https://jsonforms.discourse.group/t/rendering-images-dynamically/2588 "2025-02-04T14:00:15Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![farshad](https://avatars.discourse-cdn.com/v4/letter/f/bbe5ce/32.png) [@farshad](https://jsonforms.discourse.group/u/farshad)\
**Post date:** [February 4, 2025, 2:00pm UTC](https://jsonforms.discourse.group/t/rendering-images-dynamically/2588/1 "2025-02-04T14:00:15Z")

</div>

Hi,  
I am trying to render images dynamically using a custom renderer.

If I use `"type": "Group"` in UI Schema and `"oneOf"` in Schema, when I switch the tabs and go to the next form, the data in the previous form is cleared (as can be seen in the image below), which is what I need, but the problem is that I cannot render different images for different tabs because in the UI Schema, I can have only one image for the whole group.

 ![2](https://global.discourse-cdn.com/free1/uploads/jsonforms/original/2X/1/16c1a57b4b08f7446dd5ee1eb017858ab68ae83d.png)  
Is there a solution so that I can render one image if the tab “DESCRIPTION” is active, and render another image if the tab “DEPARTMENT” is active?  
I checked the custom react hook `useJsonForms()`, but it does not provide a state for the active tab. Does JsonForms provide other custom hooks or is there a way that I can keep track of the active tab?

// UI Schema

```auto
{
    "type": "VerticalLayout",
    "elements": [
        {
            "type": "Group",
            "label": "Person",
            "elements": [
                {
                    "type": "Control",
                    "scope": "#/properties/person"
                }
            ]
        }
    ]
}

```

// Schema

```auto
{
    "type": "object",
    "properties": {
        "person": {
            "oneOf": [
                {
                    "oneOf": [
                        {
                            "$ref": "#/definitions/description",
                            "title": "description"
                        },
                        {
                            "$ref": "#/definitions/department",
                            "title": "department"
                        }
                    ],
                    "title": "job"
                },
                {
                    "oneOf": [
                        {
                            "$ref": "#/definitions/name",
                            "title": "name"
                        }
                    ],
                    "title": "Info"
                }
            ]
        }
    },
    "definitions": {
        "description": {
            "type": "object",
            "properties": {
                "description": {
                    "type": "string"
                }
            }
        },
        "department": {
            "type": "object",
            "properties": {
                "department": {
                    "type": "string"
                }
            }
        },
        "name": {
            "type": "object",
            "properties": {
                "name": {
                    "type": "string"
                }
            }
        }
    }
}

```

I tried another solution as well. Instead of using `"type": "Group"`, I used `"type": "Categorization",`. This way, I can render different images for different tabs, but the problem is that after changing the tab, the data from the previous form persists and makes problem for form submission.

 ![1](https://global.discourse-cdn.com/free1/uploads/jsonforms/original/2X/4/45237d6d3d9e6ec4df9ad5400f368b6a21c56399.png)

// UI Schema

```auto
{
  "type": "Categorization",
  "elements": [
    {
      "type": "Category",
      "label": "Description",
      "elements": [
        {
          "type": "Control",
          "scope": "#/properties/description/properties/description"
        }
      ]
    },
    {
      "type": "Category",
      "label": "Department",
      "elements": [
        {
          "type": "Control",
          "scope": "#/properties/department/properties/department"
        }
      ]
    },
    {
      "type": "Category",
      "label": "Name",
      "elements": [
        {
          "type": "HorizontalLayout",
          "elements": [
            {
              "type": "Control",
              "scope": "#/properties/firstName"
            },
            {
              "type": "Control",
              "scope": "#/properties/secondName"
            }
          ]
        },
        {
          "type": "HorizontalLayout",
          "elements": [
            {
              "type": "Control",
              "scope": "#/properties/birthDate"
            },
            {
              "type": "Control",
              "scope": "#/properties/nationality"
            }
          ]
        }
      ]
    }
  ]
}

```

// Schema

```auto
{
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string"
    },
    "secondName": {
      "type": "string"
    },
    "birthDate": {
      "type": "string",
      "format": "date"
    },
    "nationality": {
      "type": "string",
      "enum": [
        "IT",
        "JP",
        "US",
        "Other"
      ]
    },
    "description": {
      "type": "object",
      "properties": {
        "description": {
          "type": "string"
        }
      }
    },
    "department": {
      "type": "object",
      "properties": {
        "department": {
          "type": "string"
        }
      }
    }
  }
}

```

I need a dynamic solution that works with similar forms but with different input fields, so I cannot hardcode the field names in the custom renderer.

---

<div class="post-metadata">

**Author:** ![lucas-koehler](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/lucas-koehler/32/336_2.png) [@lucas-koehler](https://jsonforms.discourse.group/u/lucas-koehler)\
**Post date:** [February 4, 2025, 4:57pm UTC](https://jsonforms.discourse.group/t/rendering-images-dynamically/2588/2 "2025-02-04T16:57:26Z")

</div>

Hi @farshad

> [@farshad](#):
>
> I checked the custom react hook `useJsonForms()`, but it does not provide a state for the active tab. Does JsonForms provide other custom hooks or is there a way that I can keep track of the active tab?

No, unfortunately JSON Forms does not keep track of active tabs in its state. It is only tracked by the respective renderers.

You could use [React contexts](https://react.dev/learn/passing-data-deeply-with-context) to pass a callback from your custom group renderer to your custom oneOf renderer. The oneOf renderer then calls the callback on tab change and the group renderer can react to this, i.e. update the image.

If you want to inject configuration to your custom renderer (i.e. relevant properties for the image), you can use the UI Schema element’s options property and add additional data  
E.g. You could have a group element like this for your custom renderer:

```auto
{
  "type": "Group",
  "elements": [
    // your elements in the group
  ],
  "options": {
    "customImageConfig": {
      // add config you need
    }
  }
}

```

In your group renderer, you can then access the config like this with `uischema.options.customImageConfig`. With `uischema` coming for the renderer’s props.

Hope that helps and best regards,  
Lucas

---

<div class="post-metadata">

**Author:** ![farshad](https://avatars.discourse-cdn.com/v4/letter/f/bbe5ce/32.png) [@farshad](https://jsonforms.discourse.group/u/farshad)\
**Post date:** [February 7, 2025, 1:47pm UTC](https://jsonforms.discourse.group/t/rendering-images-dynamically/2588/3 "2025-02-07T13:47:14Z")

</div>

Thanks lucas. I have 2 more questions.

1. I created the oneOf renderer using `rankWith(4, isOneOfControl)` and the GroupRenderer as a react component. I wrapped the `JsonForm` component by the `GroupRenderer` so that I could run both renderers at the same time.  
Is there a way to remove the `GroupRenderer` from the return statement and add it to the `renderers` array so that both renderers are executed at the same time?

```auto
const renderers = [
  ...materialRenderers,
  { tester: rankWith(4, isOneOfControl), renderer: OneOfRenderer }
  //{how to run two renderers at the same time?}
];

return (
    <ContextProvider>
      <GroupRenderer>
        <JsonForms
          schema={schema}
          uischema={uischema}
          data={data}
          renderers={renderers}
        />
      </GroupRenderer>
    </ContextProvider>
  );

```

1. If in the schema, the first oneOf points to input A and the second oneOf points to input B, is it possible to first render input B and then input A, without changing the order in the schema?

---

<div class="post-metadata">

**Author:** ![lucas-koehler](https://yyz2.discourse-cdn.com/free1/user_avatar/jsonforms.discourse.group/lucas-koehler/32/336_2.png) [@lucas-koehler](https://jsonforms.discourse.group/u/lucas-koehler)\
**Post date:** [February 10, 2025, 9:07am UTC](https://jsonforms.discourse.group/t/rendering-images-dynamically/2588/4 "2025-02-10T09:07:58Z")

</div>

Hi @farshad

> 1. I created the oneOf renderer using `rankWith(4, isOneOfControl)` and the GroupRenderer as a react component. I wrapped the `JsonForm` component by the `GroupRenderer` so that I could run both renderers at the same time.  
> Is there a way to remove the `GroupRenderer` from the return statement and add it to the `renderers` array so that both renderers are executed at the same time?

Yes, you can just add another tester for your GroupRenderer to the `renderers` array.  
If you want to use your group renderer for all groups, just do:

```ts
const renderers = [
  ...materialRenderers,
  { tester: rankWith(4, isOneOfControl), renderer: OneOfRenderer },
  { tester: rankWith(4, uiTypeIs('Group')), renderer: GroupRenderer }
];

```

If you only want to use your group renderer for UI Schema element that have a certain option (i.e. the `customImageConfig` mentioned in my first answer), you can do something like this

```ts
const renderers = [
  ...materialRenderers,
  { tester: rankWith(4, isOneOfControl), renderer: OneOfRenderer },
  { tester: and(uiTypeIs('Group'), hasOption('customImageConfig')), renderer: GroupRenderer }
];

```

> 1. If in the schema, the first oneOf points to input A and the second oneOf points to input B, is it possible to first render input B and then input A, without changing the order in the schema?

Unfortunately, this is not supported by the builtin `oneOf` renderer.

Best regards,  
Lucas

---

<div class="post-metadata">

**Author:** ![farshad](https://avatars.discourse-cdn.com/v4/letter/f/bbe5ce/32.png) [@farshad](https://jsonforms.discourse.group/u/farshad)\
**Post date:** [February 17, 2025, 7:33am UTC](https://jsonforms.discourse.group/t/rendering-images-dynamically/2588/5 "2025-02-17T07:33:27Z")

</div>

Thanks a lot. Good luck.
