Render JSONForms programmatically

Hello there,

I’m trying to use JSONForms programmatically. I want to generate the JSONForm in a container that have to be create dynamically by a component.

With Angular your template look like this:

<jsonforms
    [data]="data"
    [schema]="schema"
    [uischema]="uischema"
    [renderers]="renderers"
    [i18n]="i18n"
    [ajv]="ajv"
></jsonforms>

And all the variables are bind in the component logic.

But what I need is to put that jsonforms container dynamically through my component logic, and then initialize it with their data, schema, uischema, etc.

Is there a way to do this?

Thanks!

Hi @gmarinelli,

I do not really understand your question. If you’re already able to dynamically create components in Angular, then you can do so with JSON Forms too. What exactly does not work for you?

Hi Stefan, thanks for answer.
What I was trying to do is to create the jsonforms directly through the component logic. But the JSONForms relies on some Renderer, in this case Angular, so it’s not possible for what I found.

But no worries. I solve this by making an Angular component like this:

@Component({
  selector: '[json-forms-renderer]',
  templateUrl: './json-forms-renderer.component.html',
  styleUrls: ['./json-forms-renderer.component.scss']
})
export class JsonFormsRendererComponent {
  @Input() elementId: string = '';
  @Input() data: any;
  @Input() schema: any;
  @Input() uischema: any;
  @Output() dataChange = new EventEmitter<any>();

  renderers = [...angularMaterialRenderers];

  onDataChange(event: any) {
    this.dataChange.emit({ elementId: this.elementId, newModel: event });
  }
}

And create that component programmatically in a specified container with this method:

createJsonForms(container: HTMLElement, elementId: string, elementModel: any): void {
    const componentRef = this.viewContainerRef.createComponent(JsonFormsRendererComponent);
    componentRef.instance.data = elementModel;
    componentRef.instance.elementId = elementId;
    componentRef.instance.dataChange.subscribe((event: { elementId: string; newModel: any }) => {
      // send the change event to where correspond
    });
    container.appendChild(componentRef.location.nativeElement);
  }

Thanks anyway!
Cheers!

1 Like