From 120db7182a26348077251e30d5ada5bdbf2a9652 Mon Sep 17 00:00:00 2001 From: Gertjan van Oosten Date: Thu, 7 Dec 2023 14:41:04 +0100 Subject: [PATCH] AB#994 Add option to render enums as select dropdown An enum will be a single select, an enumset will be a multiselect. The number of visible entries in the select can be set with the htmlSize property. --- anet-dictionary.yml | 8 ++ client/src/components/FieldHelper.js | 129 ++++++++++++++++++++++++--- src/main/resources/anet-schema.yml | 2 + 3 files changed, 126 insertions(+), 13 deletions(-) diff --git a/anet-dictionary.yml b/anet-dictionary.yml index b8a9149c3b..f23779841a 100644 --- a/anet-dictionary.yml +++ b/anet-dictionary.yml @@ -643,6 +643,8 @@ fields: type: enumset label: Choose one or more of the options helpText: Help text for choosing multiple values + asA: select + htmlSize: 4 choices: opt1: label: Option 1 @@ -650,6 +652,12 @@ fields: label: Option 2 opt3: label: Option 3 + opt4: + label: Option 4 + opt5: + label: Option 5 + opt6: + label: Option 6 inputFieldName: type: text label: Text field diff --git a/client/src/components/FieldHelper.js b/client/src/components/FieldHelper.js index 31d9eedb84..53ec7b1cc0 100644 --- a/client/src/components/FieldHelper.js +++ b/client/src/components/FieldHelper.js @@ -17,6 +17,7 @@ import { Form, FormControl, FormGroup, + FormSelect, InputGroup, ListGroup, Row, @@ -520,30 +521,132 @@ ButtonToggleGroupField.propTypes = { export const RadioButtonToggleGroupField = ({ field, // { name, value, onChange, onBlur } form, // also values, setXXXX, handleXXXX, dirty, isValid, status, etc. + asA, + enableClear, ...props -}) => ( - -) +}) => + (asA === "select" && ( + + )) || ( + + ) RadioButtonToggleGroupField.propTypes = { field: PropTypes.object, - form: PropTypes.object + form: PropTypes.object, + asA: PropTypes.string, + enableClear: PropTypes.bool } export const CheckboxButtonToggleGroupField = ({ field, // { name, value, onChange, onBlur } form, // also values, setXXXX, handleXXXX, dirty, isValid, status, etc. + asA, ...props -}) => ( - -) +}) => + (asA === "select" && ( + + )) || ( + + ) CheckboxButtonToggleGroupField.propTypes = { field: PropTypes.object, - form: PropTypes.object + form: PropTypes.object, + asA: PropTypes.string +} + +export const SelectField = ({ + field, // { name, value, onChange, onBlur } + form, // contains, touched, errors, values, setXXXX, handleXXXX, dirty, isValid, status, etc. + label, + buttons, + multiple, + onChange, + className, + children, + extraColElem, + addon, + vertical, + extraAddon, + ...otherProps +}) => { + const { validationState } = getFormGroupValidationState(field, form) + if (validationState) { + className = classNames(className, "is-invalid") + } + const widgetElem = useMemo( + () => ( + { + let newValue + if (!multiple) { + // First (empty) option must be the empty string (""); replace with null when selected + newValue = e.target.value || null + } else { + newValue = [] + for (const opt of e.target.options) { + if (opt.selected) { + newValue.push(opt.value) + } + } + } + onChange(newValue) + }} + {...otherProps} + > + {!multiple && + ))} + + ), + [field, className, otherProps, buttons, multiple, onChange, validationState] + ) + return ( + + {children} + + ) +} +SelectField.propTypes = { + field: PropTypes.object, + form: PropTypes.object, + label: PropTypes.string, + buttons: PropTypes.array.isRequired, + multiple: PropTypes.bool, + onChange: PropTypes.func.isRequired, + className: PropTypes.string, + children: PropTypes.any, + extraColElem: PropTypes.object, + addon: PropTypes.object, + vertical: PropTypes.bool, + extraAddon: PropTypes.object } export default Field diff --git a/src/main/resources/anet-schema.yml b/src/main/resources/anet-schema.yml index 5071055439..e3b16b7879 100644 --- a/src/main/resources/anet-schema.yml +++ b/src/main/resources/anet-schema.yml @@ -139,6 +139,8 @@ $defs: type: string asA: type: string + htmlSize: + type: number filters: type: array uniqueItems: true