From 398d2546799a06b548ecd38ec9e2f83d50b6b0ef Mon Sep 17 00:00:00 2001 From: Fatimah Date: Mon, 26 Feb 2024 01:10:28 +0100 Subject: [PATCH] dropdown: added a dropdown for subjects --- .../SubjectAutocompleteDropdown.js | 115 ++++++++++++++++++ src/lib/forms/widgets/custom_fields/index.js | 1 + 2 files changed, 116 insertions(+) create mode 100644 src/lib/forms/widgets/custom_fields/SubjectAutocompleteDropdown.js diff --git a/src/lib/forms/widgets/custom_fields/SubjectAutocompleteDropdown.js b/src/lib/forms/widgets/custom_fields/SubjectAutocompleteDropdown.js new file mode 100644 index 00000000..1b7fbc6c --- /dev/null +++ b/src/lib/forms/widgets/custom_fields/SubjectAutocompleteDropdown.js @@ -0,0 +1,115 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { RemoteSelectField } from "../../RemoteSelectField"; +import { Field, getIn } from "formik"; +import { FieldLabel } from "../../FieldLabel"; + +export class SubjectAutocompleteDropdown extends Component { + serializeSubjects = (subjects) => + subjects.map((subject) => { + const scheme = subject.scheme ? `(${subject.scheme}) ` : ""; + return { + text: scheme + subject.subject, + value: subject.subject, + key: subject.subject, + ...(subject.id ? { id: subject.id } : {}), + subject: subject.subject, + }; + }); + + prepareSuggest = (searchQuery) => { + const { limitTo } = this.props; + return limitTo === "" || limitTo === "all" + ? searchQuery + : `${limitTo}:${searchQuery}`; + }; + + render() { + const { + fieldPath, + required, + multiple, + placeholder, + clearable, + label, + icon, + width, + allowAdditions, + noQueryMessage, + } = this.props; + const labelContent = label ? ( + + ) : ( + <> + {/* Placeholder label for alignment purposes */} + + + ); + + return ( + + {({ form: { values } }) => ( + ({ + text: value, + value: value, + key: value, + subject: value, + })} + suggestionAPIUrl="/api/subjects" + onValueChange={({ formikProps }, selectedSuggestions) => { + formikProps.form.setFieldValue( + fieldPath, + selectedSuggestions.map((subject) => ({ + subject: subject.subject, + })) + ); + }} + label={labelContent} + value={getIn(values, fieldPath, []).map((val) => val.subject)} + allowAdditions={allowAdditions} + width={width} + /> + )} + + ); + } +} + +SubjectAutocompleteDropdown.propTypes = { + fieldPath: PropTypes.string.isRequired, + limitTo: PropTypes.string, + label: PropTypes.string, + icon: PropTypes.string, + required: PropTypes.bool, + multiple: PropTypes.bool, + clearable: PropTypes.bool, + placeholder: PropTypes.string, + width: PropTypes.number, + allowAdditions: PropTypes.bool, + noQueryMessage: PropTypes.string, +}; + +SubjectAutocompleteDropdown.defaultProps = { + required: false, + limitTo: "", + label: "", + icon: undefined, + multiple: true, + clearable: true, + placeholder: "Search for a subject by name", + width: undefined, + noQueryMessage: "Search or create subjects...", + allowAdditions: true, +}; diff --git a/src/lib/forms/widgets/custom_fields/index.js b/src/lib/forms/widgets/custom_fields/index.js index b57a438d..726f6102 100644 --- a/src/lib/forms/widgets/custom_fields/index.js +++ b/src/lib/forms/widgets/custom_fields/index.js @@ -1 +1,2 @@ export { CustomFields } from "./CustomFields"; +export { SubjectAutocompleteDropdown } from "./SubjectAutocompleteDropdown";