This is the uischema I am trying to render
" {
“type”: “Control”,
“scope”: “#/properties/options/properties/query”,
“label”: “Query”,
“options”: {
“format”: “radio”,
“readonly”: true
}
}
I am using angular and jsonforms 3.5.1.
I have created following custom renderer component and
import { Component } from '@angular/core';
import { JsonFormsAngularService,JsonFormsControl } from '@jsonforms/angular';
import { MatRadioModule, MatRadioChange } from '@angular/material/radio';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-radio-control',
standalone: true,
imports: [
CommonModule,
MatRadioModule
],
template: `
<div class="radio-control-container">
<label class="radio-label">{{ label }}</label>
<mat-radio-group
[disabled]="!enabled"
[value]="data"
(change)="onChange($event)"
[id]="id">
<mat-radio-button
*ngFor="let option of schema.enum"
[value]="option.const"
class="radio-button">
{{ option.title }}
</mat-radio-button>
</mat-radio-group>
<div class="error-text" *ngIf="error">{{ error }}</div>
</div>
`,
styles: [`
.radio-control-container {
display: flex;
flex-direction: column;
margin: 1rem 0;
}
.radio-label {
font-weight: 500;
margin-bottom: 0.5rem;
}
mat-radio-group {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.radio-button {
margin: 0.25rem 0;
}
.error-text {
color: red;
font-size: 0.75rem;
margin-top: 0.25rem;
}
`]
})
export class RadioControlRenderer extends JsonFormsControl {
constructor(jsonFormsService: JsonFormsAngularService) {
super(jsonFormsService);
}
override onChange(event: MatRadioChange): void {
this.data= event.value;
}
}
and custom renderer tester
import { and, isEnumControl, RankedTester, rankWith } from "@jsonforms/core";
export const radioControlTester: RankedTester = rankWith(3, isEnumControl);
and then register tester and renderer in app-component renderer
export class AppComponent{
title = 'jsonforms';
renderers = [
{
//register a renderer for the radio control
tester: radioControlTester,renderer: RadioControlRenderer
},
...angularMaterialRenderers,
];
but I keep getting the following error while displaying radio component.
No applicable renderer found!
Hi @jmpatel,
Can you also post the schema
which you use together with the uischema
?
“No applicable renderer found” errors are usually caused by a mismatch between schema/uischema, or by using JSON Schema features not supported by the renderer set in question.
The schema
{
"type": "object",
"required": ["driverconfig"],
"properties": {
"driverconfig": {
"type": "object",
"properties": {
"drivername": {
"type": "string",
"title": "ABC",
"description": "ABC v8.00.0002"
},
"driverOpts": {
"type": "object",
"properties": {
"query": {
"$ref": "#/definitions/YesNo"
},
"dupreq": {
"$ref": "#/definitions/Overwrite"
},
"qupdt": {
"$ref": "#/definitions/Result"
},
"ordersid,strip": {
"$ref": "#/definitions/YesNo"
}
}
}
},
"required": ["drivername"]
}
},
"definitions": {
"YesNo": {
"type": "string",
"oneOf": [
{
"const": "Yes",
"title": "Yes"
},
{
"const": "No",
"title": "No"
}
]
},
"Overwrite": {
"type": "string",
"oneOf": [
{
"const": "Overwrite",
"title": "Overwrite"
}
]
},
"Result": {
"type": "string",
"oneOf": [
{
"const": "Result",
"title": "Result"
}
]
}
}
}
the UIschema
{
"type": "VerticalLayout",
"elements": [
{
"type": "Group",
"label": "Driver Configuration",
"elements": [
{
"type": "Control",
"scope": "#/properties/driverconfig/properties/drivername",
"label": "Driver Name",
"options": {
"showDescription": true,
"readonly": true
}
},
{
"type": "Group",
"label": "Driver Options",
"elements": [
{
"type": "Control",
"scope": "#/properties/driverOpts/properties/query",
"label": "Query",
"options": {
"format": "radio"
}
},
{
"type": "Control",
"scope": "#/properties/driverOpts/properties/dupreq",
"label": "Duplicate Request"
},
{
"type": "Control",
"scope": "#/properties/driverconfig/properties/driverOpts/properties/qupdt",
"label": "Query Update"
},
{
"type": "Control",
"scope": "#/properties/driverOpts/properties/ordersid,strip",
"label": "Orders Id Strip",
"options": {
"format": "radio"
}
}
]
}
]
}
],
"options": {
"margin": "1em",
"padding": "1em"
}
}
There was a mistake I was doing in scope so after doing proper mapping the error related to “No applicable renderer found” is gone. But I am not able to see the radio button in UI. My new screen looks as follows.
when I click on empty square box in the bottom
then screen keep adding one more line item
so everything is not displayed at the time of screen loading but it requires additional click on empty square box, which keeps bringing new line items.
How it can be fixed.
and I don’t see the radio button, but it converted into the text. What need to be done to display as a button.
Hi @jmpatel,
We don’t support oneOf
based “enums” out of the box in Angular Material. For this you either need to implement it manually or reuse one of the core bindings.
The existing enum renderer manually determines the options here. You could replicate the logic but handle oneOf
enums instead.
All other renderer set use the enum and oneOf option utils to determine the options to show in the UI, via the mapStateToEnumControlProps
and mapStateToOneOfEnumControlProps
bindings. So the cleaner option would be to actually reuse the bindings instead of manually doing an own determination within the Angular Material renderers.
I would suggest reusing the mappers. If you like you can also contribute this improvement to the JSON Forms repository.