feature/fix-required-radio-buttons (#525)
* ignore validations for radio booleans from the custom form w/ burnettk * use carbon for radio buttons * added comment about error message without label --------- Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
parent
34a0323c4d
commit
acc918b664
|
@ -152,8 +152,18 @@ export default function CustomForm({
|
|||
formDataToCheck: any,
|
||||
propertyKey: string,
|
||||
errors: any,
|
||||
jsonSchema: any
|
||||
jsonSchema: any,
|
||||
uiSchemaPassedIn?: any
|
||||
) => {
|
||||
// this validation only applies to checkboxes,
|
||||
// other forms of booleans are validated differently
|
||||
if (
|
||||
uiSchemaPassedIn &&
|
||||
'ui:widget' in uiSchemaPassedIn &&
|
||||
uiSchemaPassedIn['ui:widget'] !== 'checkbox'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
jsonSchema.required &&
|
||||
jsonSchema.required.includes(propertyKey) &&
|
||||
|
@ -169,7 +179,8 @@ export default function CustomForm({
|
|||
const checkFieldsWithCustomValidations = (
|
||||
jsonSchema: any,
|
||||
formDataToCheck: any,
|
||||
errors: any
|
||||
errors: any,
|
||||
uiSchemaPassedIn?: any
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
) => {
|
||||
// if the jsonSchema has an items attribute then assume the element itself
|
||||
|
@ -177,9 +188,21 @@ export default function CustomForm({
|
|||
const jsonSchemaToUse =
|
||||
'items' in jsonSchema ? jsonSchema.items : jsonSchema;
|
||||
|
||||
let uiSchemaToUse = uiSchemaPassedIn;
|
||||
if (!uiSchemaToUse) {
|
||||
uiSchemaToUse = uiSchema;
|
||||
}
|
||||
if ('items' in uiSchemaToUse) {
|
||||
uiSchemaToUse = uiSchemaToUse.items;
|
||||
}
|
||||
|
||||
if ('properties' in jsonSchemaToUse) {
|
||||
Object.keys(jsonSchemaToUse.properties).forEach((propertyKey: string) => {
|
||||
const propertyMetadata = jsonSchemaToUse.properties[propertyKey];
|
||||
let currentUiSchema: any = null;
|
||||
if (propertyKey in uiSchemaToUse) {
|
||||
currentUiSchema = uiSchemaToUse[propertyKey];
|
||||
}
|
||||
if ('minimumDate' in propertyMetadata) {
|
||||
checkMinimumDate(
|
||||
formDataToCheck,
|
||||
|
@ -195,7 +218,8 @@ export default function CustomForm({
|
|||
formDataToCheck,
|
||||
propertyKey,
|
||||
errors,
|
||||
jsonSchemaToUse
|
||||
jsonSchemaToUse,
|
||||
currentUiSchema
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -213,7 +237,8 @@ export default function CustomForm({
|
|||
checkFieldsWithCustomValidations(
|
||||
propertyMetadata,
|
||||
item,
|
||||
errorsToSend
|
||||
errorsToSend,
|
||||
currentUiSchema
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ function CheckboxWidget(props: WidgetProps) {
|
|||
title={commonAttributes.tooltipText}
|
||||
autoFocus={autofocus}
|
||||
invalid={commonAttributes.invalid}
|
||||
invalidText={commonAttributes.errorMessageForField}
|
||||
invalidText={commonAttributes.errorMessageForFieldWithoutLabel}
|
||||
helperText={commonAttributes.helperText}
|
||||
labelText={
|
||||
required
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import React from "react";
|
||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import FormLabel from "@mui/material/FormLabel";
|
||||
import Radio from "@mui/material/Radio";
|
||||
import RadioGroup from "@mui/material/RadioGroup";
|
||||
import { WidgetProps } from "@rjsf/utils";
|
||||
import React from 'react';
|
||||
import { RadioButtonGroup, RadioButton } from '@carbon/react';
|
||||
import { WidgetProps } from '@rjsf/utils';
|
||||
import { getCommonAttributes } from '../../helpers';
|
||||
|
||||
const RadioWidget = ({
|
||||
function RadioWidget({
|
||||
id,
|
||||
schema,
|
||||
options,
|
||||
|
@ -17,11 +15,19 @@ const RadioWidget = ({
|
|||
onChange,
|
||||
onBlur,
|
||||
onFocus,
|
||||
}: WidgetProps) => {
|
||||
uiSchema,
|
||||
rawErrors,
|
||||
}: WidgetProps) {
|
||||
const { enumOptions, enumDisabled } = options;
|
||||
|
||||
const _onChange = (_: any, value: any) =>
|
||||
onChange(schema.type == "boolean" ? value !== "false" : value);
|
||||
const _onChange = (newValue: any, _radioButtonId: any) => {
|
||||
if (schema.type === 'boolean') {
|
||||
const v: any = newValue === 'true' || newValue === true;
|
||||
onChange(v);
|
||||
} else {
|
||||
onChange(newValue);
|
||||
}
|
||||
};
|
||||
const _onBlur = ({ target: { value } }: React.FocusEvent<HTMLInputElement>) =>
|
||||
onBlur(id, value);
|
||||
const _onFocus = ({
|
||||
|
@ -30,43 +36,39 @@ const RadioWidget = ({
|
|||
|
||||
const row = options ? options.inline : false;
|
||||
|
||||
const commonAttributes = getCommonAttributes(
|
||||
label,
|
||||
schema,
|
||||
uiSchema,
|
||||
rawErrors
|
||||
);
|
||||
|
||||
// pass values in as strings so we can support both boolean and string radio buttons
|
||||
return (
|
||||
<>
|
||||
<RadioGroup
|
||||
<RadioButtonGroup
|
||||
id={id}
|
||||
name={id}
|
||||
value={`${value}`}
|
||||
row={row as boolean}
|
||||
legendText={commonAttributes.helperText}
|
||||
valueSelected={`${value}`}
|
||||
invalid={commonAttributes.invalid}
|
||||
invalidText={commonAttributes.errorMessageForFieldWithoutLabel}
|
||||
disabled={disabled || readonly}
|
||||
onChange={_onChange}
|
||||
onBlur={_onBlur}
|
||||
onFocus={_onFocus}
|
||||
>
|
||||
{Array.isArray(enumOptions) &&
|
||||
enumOptions.map((option) => {
|
||||
const itemDisabled =
|
||||
Array.isArray(enumDisabled) &&
|
||||
enumDisabled.indexOf(option.value) !== -1;
|
||||
const radio = (
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Radio
|
||||
name={id}
|
||||
return (
|
||||
<RadioButton
|
||||
id={`${id}-${option.value}`}
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label={`${option.label}`}
|
||||
labelText={option.label}
|
||||
value={`${option.value}`}
|
||||
key={option.value}
|
||||
disabled={disabled || itemDisabled || readonly}
|
||||
/>
|
||||
);
|
||||
|
||||
return radio;
|
||||
})}
|
||||
</RadioGroup>
|
||||
</>
|
||||
</RadioButtonGroup>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default RadioWidget;
|
||||
|
|
|
@ -25,12 +25,17 @@ export const getCommonAttributes = (
|
|||
}
|
||||
}
|
||||
|
||||
// some rjsf validations add in labels by default so avoid showing it twice
|
||||
let errorMessageForFieldWithoutLabel = null;
|
||||
|
||||
let invalid = false;
|
||||
let errorMessageForField = null;
|
||||
if (rawErrors && rawErrors.length > 0) {
|
||||
invalid = true;
|
||||
[errorMessageForFieldWithoutLabel] = rawErrors;
|
||||
if ('validationErrorMessage' in schema) {
|
||||
errorMessageForField = (schema as any).validationErrorMessage;
|
||||
errorMessageForFieldWithoutLabel = errorMessageForField;
|
||||
} else {
|
||||
errorMessageForField = `${labelToUse.replace(/\*$/, '')} ${rawErrors[0]}`;
|
||||
}
|
||||
|
@ -41,6 +46,7 @@ export const getCommonAttributes = (
|
|||
label: labelToUse,
|
||||
invalid,
|
||||
errorMessageForField,
|
||||
errorMessageForFieldWithoutLabel,
|
||||
labelWithRequiredIndicator,
|
||||
tooltipText,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue