Multi Select Dropdown

Hi I am trying to create a custom renderer for a multi select dropdown, however, it seems as thought my tester is not working.

Here is the MultiSelect.js

import React, { useMemo } from ‘react’;
import PropTypes from ‘prop-types’;
import { MenuItem, Select } from ‘@mui/material’;
import merge from ‘lodash/merge’;

export const i18nDefaults = {
‘enum.none’: ‘None’
};

export const MuiSelect = ({ data, className, id, enabled, schema, uischema, path, handleChange, options, config, t }) => {
const appliedUiSchemaOptions = merge({}, config, uischema.options);
const noneOptionLabel = useMemo(
() => t(‘enum.none’, i18nDefaults[‘enum.none’], { schema, uischema, path }),
[t, schema, uischema, path]
);

return (
<Select
className={className}
id={id}
multiple
disabled={!enabled}
autoFocus={appliedUiSchemaOptions.focus}
value={data !== undefined ? data : }
onChange={ev => {
handleChange(path, ev.target.value || undefined);
}}
fullWidth={true}
variant={‘standard’}>
{[
<MenuItem value={‘’} key=“jsonforms.enum.none”>
{noneOptionLabel}

].concat(
options.map(optionValue => (

{optionValue.label}

))
)}

);
};

MuiSelect.propTypes = {
options: PropTypes.arrayOf(PropTypes.any),
className: PropTypes.any,
id: PropTypes.any,
enabled: PropTypes.any,
schema: PropTypes.any,
uischema: PropTypes.any,
path: PropTypes.any,
handleChange: PropTypes.any,
config: PropTypes.any,
t: PropTypes.any,
data: PropTypes.any
};

Here is MultiSelectControl.js:

import React from ‘react’;
import PropTypes from ‘prop-types’;
import { isEnumControl, rankWith, and, uiTypeIs, schemaMatches, schemaSubPathMatches, hasType } from ‘@jsonforms/core’;
import { withJsonFormsEnumProps, withTranslateProps } from ‘@jsonforms/react’;
import { MuiSelect } from ‘./multiSelect’;
import merge from ‘lodash/merge’;
import { MuiAutocomplete, MaterialInputControl } from ‘@jsonforms/material-renderers’;

export const MultiSelectControl = props => {
const { config, uischema, errors } = props;
const appliedUiSchemaOptions = merge({}, config, uischema.options);
const isValid = errors.length === 0;
return appliedUiSchemaOptions.autocomplete === false ? (
<MaterialInputControl {…props} input={MuiSelect} />
) : (
<MuiAutocomplete {…props} isValid={isValid} />
);
};

const hasOneOfItems = schema =>
schema.oneOf !== undefined &&
schema.oneOf.length > 0 &&
schema.oneOf.every(entry => {
return entry.const !== undefined;
});

const hasEnumItems = schema => schema.type === ‘string’ && schema.enum !== undefined;

export const multiSelectControlTester = rankWith(
9,
isEnumControl,
and(
uiTypeIs(‘Control’),
and(
schemaMatches(schema => hasType(schema, ‘array’) && !Array.isArray(schema.items) && schema.uniqueItems === true),
schemaSubPathMatches(‘items’, schema => {
return hasOneOfItems(schema) || hasEnumItems(schema);
})
)
)
);

MultiSelectControl.propTypes = {
data: PropTypes.any,
path: PropTypes.any,
errors: PropTypes.any,
options: PropTypes.arrayOf(PropTypes.any),
addItem: PropTypes.any,
removeItem: PropTypes.any,
handleChange: PropTypes.any,
schema: PropTypes.any,
visible: PropTypes.any,
label: PropTypes.any,
uischema: PropTypes.any,
required: PropTypes.any,
config: PropTypes.any
};

// HOC order can be reversed with Improve React HOC types · Issue #1987 · eclipsesource/jsonforms · GitHub
export default withJsonFormsEnumProps(withTranslateProps(MultiSelectControl));

Hi @avwchapman,

we need more information here, for example what exactly the problem is that you are facing and how your JSON Schema looks like.

It would be great if you could reproduce your problem within the JSON Forms React seed and then send us a branch/fork for us to take a more detailed look. This would save a lot of back-and-forth communication.

Here is my uiSchema:

Screenshot 2023-10-16 at 10.52.53 AM

This is my schema:

The issue I am experiencing is this question is still coming up as a checkbox group

Your tester seems to be incorrect. You hand over 3 parameters to rankWith although it only expects 2. I would recommend starting with a very simply tester to make sure it works and then gradually switch to more complex ones.

In your case you could for example use

rankWith(10000, scopeEndsWith('7'));

And only then gradually replace it with more generic alternatives.