Passing errors prop to custom renderer

I am wondering how I can utilize the errors prop in my custom renderer to disable the submit button when there are errors present.

import React, { useState, useMemo } from ‘react’;
import PropTypes from ‘prop-types’;
import merge from ‘lodash/merge’;
import {
Button,
Hidden,
Step,
StepButton,
MobileStepper,
Box,
Paper,
Stepper,
ThemeProvider,
StepLabel,
Typography
} from ‘@mui/material’;
import {
and,
categorizationHasCategory,
isVisible,
optionIs,
rankWith,
uiTypeIs,
deriveLabelForUISchemaElement,
defaultTranslator
} from ‘@jsonforms/core’;
import { withJsonFormsLayoutProps, withTranslateProps } from ‘@jsonforms/react’;
import { MaterialLayoutRenderer, withAjvProps } from ‘./materialLayout’;
import PersonAddAlt1Icon from ‘@mui/icons-material/PersonAddAlt1’;
import { theme } from ‘…/…/…/styles/theme’;

export const materialCategorizationStepperTester = rankWith(
3,
and(uiTypeIs(‘Categorization’), categorizationHasCategory, optionIs(‘variant’, ‘stepper’))
);

export const MaterialCategorizationStepperLayoutRenderer = props => {
const [activeCategory, setActiveCategory] = useState(0);

const handleStep = step => {
setActiveCategory(step);
};

const { data, path, renderers, schema, uischema, visible, cells, config, ajv } = props;

const categorization = uischema;

const appliedUiSchemaOptions = merge({}, config, uischema.options);

const buttonWrapperStyle = {
textAlign: ‘right’,
width: ‘100%’,
margin: ‘1em auto’
};

const buttonNextStyle = {
float: ‘right’
};

const buttonStyle = {
marginRight: ‘1em’
};

const categories = useMemo(
() => categorization.elements.filter(category => isVisible(category, data, undefined, ajv)),
[categorization, data, ajv]
);

const childProps = {
elements: categories[activeCategory].elements,
schema,
path,
direction: ‘column’,
visible,
renderers,
cells
};

const tabLabels = useMemo(() => {
return categories.map(e => deriveLabelForUISchemaElement(e, defaultTranslator));
}, [categories, defaultTranslator]);

return (

<Box sx={{ display: ‘flex’ }}>
<Paper
position=“static”
data-testid=“vertical-stepper”
sx={{
backgroundColor: ‘dark.main’,
maxWidth: 270,
display: ‘inline-block’
}}
elevation={3}
square={true}>
<Typography
sx={{
fontSize: 20,
padding: 3,
color: ‘dark.contrastText’,
display: ‘flex’,
alignItems: ‘center’
}}>
<PersonAddAlt1Icon color=“secondary” sx={{ fontSize: ‘inherit’, marginRight: 2, verticalAlign: ‘middle’ }} />
{schema.title}

<Stepper
className=“vertical-stepper”
nonLinear
activeStep={activeCategory}
orientation=“vertical”
position=“static”
connector={

}
sx={{ padding: 3 }}>
{categories.map((, idx) => (

<StepButton onClick={() => handleStep(idx)} data-testid={‘step-’ + idx}>
{tabLabels[idx]}


))}


<Box component=“main” sx={{ flexGrow: 1, p: 3, height: ‘calc(100vh - 64px)’, overflowY: ‘scroll’ }}>

<Typography sx={{ fontSize: 25, textAlign: ‘center’, p: 1, fontWeight: ‘bold’ }}>
{tabLabels[activeCategory]}

<MobileStepper
data-testid=“progress-bar”
activeStep={activeCategory}
variant=“progress”
position=“static”
steps={categories.length}
sx={{ justifyContent: ‘center’, alignItems: ‘center’, display: ‘flex’ }}>
{categories.map((
, idx) => (
<Step key={tabLabels[idx]} sx={{ padding: 50 }}>
<StepButton onClick={() => handleStep(idx)}>{tabLabels[idx]}

))}


<MaterialLayoutRenderer {…childProps} sx={{ overflowY: ‘scroll’ }} />

{appliedUiSchemaOptions.showNavButtons ? (

= categories.length - 1}
onClick={() => handleStep(activeCategory + 1)}>
Next

<Button
style={buttonStyle}
color=“secondary”
variant=“contained”
disabled={activeCategory <= 0}
onClick={() => handleStep(activeCategory - 1)}>
Previous


<Button color=“primary” sx={{ px: 6, py: 2 }}>
Submit



) : (
<></>
)}




);
};

MaterialCategorizationStepperLayoutRenderer.propTypes = {
data: PropTypes.any,
path: PropTypes.any,
renderers: PropTypes.any,
schema: PropTypes.any,
uischema: PropTypes.any,
visible: PropTypes.any,
cells: PropTypes.any,
config: PropTypes.any,
ajv: PropTypes.any
};

export default withAjvProps(withTranslateProps(withJsonFormsLayoutProps(MaterialCategorizationStepperLayoutRenderer)));

Hi @avwchapman,

To disable the button you need to set the disabled attribute appropriately. Note that the stepper is a layout element and therefore does not have associated errors. In case your steps are scoped objects, you can however easily determine whether there are errors.

You can access the form wide errors this way:

const ctx = useJsonForms();
const allErrors = ctx.core.errors

You can then filter them according to your needs and appropriately disable the “submit”.

Great, thank you! Is there a way I can also access additional errors in my custom stepper?

Hi @avwchapman,

The additionalErrors are placed next to the errors, see here. So in the example above you can access them via ctx.core.additionalErrors.