use a unique id for radio buttons in rjsf (#1200)

* use a unique id for radio buttons in rjsf

* moved comments about usage of makeid in rjsf to helper function that gets used

* useMemo to store the uniqueId w/ burnettk

---------

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
jasquat 2024-03-13 14:33:12 +00:00 committed by GitHub
parent 64910810ef
commit c281e28bbb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 16 deletions

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { useMemo } from 'react';
import { Checkbox } from '@carbon/react';
import { WidgetProps } from '@rjsf/utils';
import { getCommonAttributes, makeid } from '../../helpers';
@ -19,6 +19,11 @@ function CheckboxWidget(props: WidgetProps) {
rawErrors,
required,
} = props;
const uniqueId: string = useMemo(() => {
return makeid(10, 'checkbox-');
}, []);
const _onChange = (_: any, newValue: any) => {
// if this field is required and it is not checked then change the value to undefined
// otherwise rjsf will not flag this field as invalid
@ -42,12 +47,6 @@ function CheckboxWidget(props: WidgetProps) {
rawErrors
);
// if the parent rjsf schema is not of type "object", then rjsf sends "root" through as the id.
// this creates issues with the carbon checkbox where it will not accept any clicks to the checkbox
// so add fuzz to the id to ensure it is unique.
// https://github.com/rjsf-team/react-jsonschema-form/issues/1824
const uniqueId = makeid(10);
return (
<Checkbox
id={uniqueId}

View File

@ -1,14 +1,13 @@
import React from 'react';
import React, { useMemo } from 'react';
import { RadioButtonGroup, RadioButton } from '@carbon/react';
import { WidgetProps } from '@rjsf/utils';
import { getCommonAttributes } from '../../helpers';
import { getCommonAttributes, makeid } from '../../helpers';
function RadioWidget({
id,
schema,
options,
value,
required,
disabled,
readonly,
label,
@ -18,7 +17,11 @@ function RadioWidget({
uiSchema,
rawErrors,
}: WidgetProps) {
const { enumOptions, enumDisabled } = options;
const { enumOptions } = options;
const uniqueId: string = useMemo(() => {
return makeid(10, 'radio-button-');
}, []);
const _onChange = (newValue: any, _radioButtonId: any) => {
if (schema.type === 'boolean') {
@ -47,8 +50,8 @@ function RadioWidget({
// pass values in as strings so we can support both boolean and string radio buttons
return (
<RadioButtonGroup
id={id}
name={id}
id={uniqueId}
name={uniqueId}
legendText={commonAttributes.helperText}
valueSelected={`${value}`}
invalid={commonAttributes.invalid}
@ -63,7 +66,7 @@ function RadioWidget({
enumOptions.map((option) => {
return (
<RadioButton
id={`${id}-${option.value}`}
id={`${uniqueId}-${option.value}`}
labelText={option.label}
value={`${option.value}`}
/>

View File

@ -52,9 +52,14 @@ export const getCommonAttributes = (
};
};
// this is useful for certain carbon elements where if they do not have a unique id on groups
// then odd things will happen. Examples:
// * radio button groups will deselect the item from a group when selecting one from a different group
// * checkboxes will not accept any clicks to the checkbox
// https://github.com/rjsf-team/react-jsonschema-form/issues/1824
// https://stackoverflow.com/a/1349426/6090676
export const makeid = (length: number) => {
let result = '';
export const makeid = (length: number, prefix: string = '') => {
let result = prefix;
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
for (let i = 0; i < length; i += 1) {