Skip to content

Commit f574d71

Browse files
Added autocomplete course dropdown for Generate form (#1600)
1 parent 4a60e61 commit f574d71

File tree

7 files changed

+1948
-1446
lines changed

7 files changed

+1948
-1446
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Updated the Zoom In/Zoom Out buttons on the graph page to Awesome Icons from +/-
1010
- Added the React ErrorBoundary library and implemented an ErrorBoundary for the Graph component in the Container component and `js/components/draw/main.js`
1111
- Updated the export button on the graph and grid pages to Awesome Icons; also added highlight effect and tooltip popup on hover
12+
- Added an autocomplete feature to the search bar `js/components/generate/GenerateForm`, also rewrote tests related to this feature
1213

1314
### 🐛 Bug fixes
1415

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React, { useEffect, useState } from "react"
2+
import Autocomplete from "@mui/material/Autocomplete"
3+
import Chip from "@mui/material/Chip"
4+
import { useField } from "formik"
5+
import PropTypes from "prop-types"
6+
7+
export default function AutocompleteDropdown({
8+
name,
9+
placeholder,
10+
id,
11+
onSelectedChange,
12+
...props
13+
}) {
14+
const [, , helpers] = useField(name)
15+
const { setValue } = helpers
16+
const [optionList, setOptionList] = useState([])
17+
18+
useEffect(() => {
19+
fetch("/courses")
20+
.then(response => response.text())
21+
.then(data => {
22+
const courses = data.split("\n").map(course => course.substring(0, 8))
23+
setOptionList(courses)
24+
})
25+
}, [])
26+
27+
return (
28+
<Autocomplete
29+
multiple
30+
onChange={(event, newValues) => {
31+
onSelectedChange(newValues)
32+
setValue(newValues.join(", "))
33+
}}
34+
options={optionList}
35+
includeInputInList
36+
disableClearable
37+
disableCloseOnSelect
38+
popupIcon={null}
39+
sx={{ width: "100%" }}
40+
renderValue={(value, getItemProps) =>
41+
value.map((option, index) => {
42+
const { key, ...itemProps } = getItemProps({ index })
43+
return <Chip variant="outlined" label={option} key={key} {...itemProps} />
44+
})
45+
}
46+
renderInput={params => (
47+
<div ref={params.InputProps.ref}>
48+
<input
49+
aria-label={name}
50+
className="autocomplete-input"
51+
type="text"
52+
{...params.inputProps}
53+
placeholder={placeholder}
54+
id={id}
55+
/>
56+
</div>
57+
)}
58+
{...props}
59+
/>
60+
)
61+
}
62+
63+
AutocompleteDropdown.propTypes = {
64+
name: PropTypes.string,
65+
placeholder: PropTypes.string,
66+
id: PropTypes.string,
67+
onSelectedChange: PropTypes.func,
68+
}

js/components/generate/GenerateForm.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ import { Tooltip } from "react-tooltip"
66
import { Graph, populateHybridRelatives } from "../graph/Graph"
77
import Disclaimer from "../common/Disclaimer"
88
import { NavBar } from "../common/NavBar.js.jsx"
9+
import AutocompleteDropdown from "./AutocompleteDropdown.js"
910

1011
export default class GenerateForm extends React.Component {
1112
constructor(props) {
1213
super(props)
1314
this.state = {
1415
fceCount: 0,
16+
selectedCourses: [],
1517
}
1618

1719
this.graph = React.createRef()
@@ -25,6 +27,10 @@ export default class GenerateForm extends React.Component {
2527
this.setState({ fceCount: this.state.fceCount + credits })
2628
}
2729

30+
handleCoursesChange = newCourse => {
31+
this.setState({ selectedCourses: newCourse })
32+
}
33+
2834
handleSubmit = (values, { setErrors }) => {
2935
const data = {}
3036

@@ -330,7 +336,7 @@ export default class GenerateForm extends React.Component {
330336
courses: "",
331337
programs: "",
332338
taken: "",
333-
departments: "CSC, MAT, STA",
339+
departments: "",
334340
maxDepth: 0,
335341
location: ["utsg"],
336342
includeRaws: false,
@@ -377,19 +383,25 @@ export default class GenerateForm extends React.Component {
377383
></a>
378384
<Tooltip id="courses-tooltip" place="right" />
379385
</div>
380-
<Field
386+
<AutocompleteDropdown
381387
id="courses"
388+
aria-label="courses"
382389
name="courses"
383-
type="text"
384390
placeholder="e.g., CSC207H1, CSC324H1"
391+
onSelectedChange={this.handleCoursesChange}
392+
className="autocomplete"
385393
/>
386394
<div className="error-container">
387395
<ErrorMessage
388396
className="error-message"
389397
name="courses"
398+
type="text"
390399
component="div"
391400
/>
392401
</div>
402+
<h1 className="chosen-courses">
403+
Selected Courses: {this.state.selectedCourses.join(", ")}
404+
</h1>
393405
</>
394406
)}
395407

0 commit comments

Comments
 (0)