Skip to content

Commit ff2fe8e

Browse files
authored
Merge pull request #27 from dfberry/dfberry/0119-fix-suggestions
Client - Material UI - autocomplete
2 parents 08c5cdd + 2ec36ee commit ff2fe8e

File tree

10 files changed

+126
-129
lines changed

10 files changed

+126
-129
lines changed

client/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/src/App/App.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
.main--home {
99
min-height: 40em;
10+
width: 50%;
1011
}
1112
.main--details {
1213
min-height: 40em;

client/src/components/Results/Results.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default function Results(props) {
1717

1818
return (
1919
<div>
20-
<p className="results-info">Showing {beginDocNumber}-{endDocNumber} of {props.count.toLocaleString()} results</p>
20+
<p className="results-info">Showing {beginDocNumber}-{endDocNumber} of {props.count.toLocaleString()} results for <b>{props.query}</b></p>
2121
<div className="row row-cols-md-5 results">
2222
{results}
2323
</div>
Lines changed: 77 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,88 @@
1-
import React, {useState, useEffect} from 'react';
1+
import React, { useState, useEffect } from 'react';
2+
import { TextField, Autocomplete, Button, Box } from '@mui/material';
23
import axios from '../../axios.js';
3-
import Suggestions from './Suggestions/Suggestions';
44

5-
import "./SearchBar.css";
5+
export default function SearchBar2({ postSearchHandler, query }) {
6+
const [q, setQ] = useState(() => query || '');
7+
const [suggestions, setSuggestions] = useState([]);
68

7-
export default function SearchBar(props) {
9+
const search = (value) => {
10+
console.log(`search: ${value}`);
11+
postSearchHandler(value);
12+
};
813

9-
let [q, setQ] = useState("");
10-
let [suggestions, setSuggestions] = useState([]);
11-
let [showSuggestions, setShowSuggestions] = useState(false);
14+
useEffect(() => {
15+
console.log(`useEffect getSuggestions: ${q}`);
16+
if (q) {
17+
axios.post('/api/suggest', { q, top: 5, suggester: 'sg' })
18+
.then(response => {
19+
setSuggestions(response.data.suggestions.map(s => s.text));
20+
}).catch (error =>{
21+
console.log(error);
22+
setSuggestions([]);
23+
});
24+
}}, [q]);
1225

13-
const onSearchHandler = () => {
14-
props.postSearchHandler(q);
15-
setShowSuggestions(false);
16-
}
17-
18-
const suggestionClickHandler = (s) => {
19-
document.getElementById("search-box").value = s;
20-
setShowSuggestions(false);
21-
props.postSearchHandler(s);
22-
}
2326

24-
const onEnterButton = (event) => {
25-
if (event.keyCode === 13) {
26-
onSearchHandler();
27-
}
28-
}
29-
30-
const onChangeHandler = () => {
31-
var searchTerm = document.getElementById("search-box").value;
32-
setShowSuggestions(true);
33-
setQ(searchTerm);
34-
35-
// use this prop if you want to make the search more reactive
36-
if (props.searchChangeHandler) {
37-
props.searchChangeHandler(searchTerm);
38-
}
39-
}
27+
const onInputChangeHandler = (event, value) => {
28+
console.log(`onInputChangeHandler: ${value}`);
29+
setQ(value);
30+
};
4031

41-
useEffect(_ =>{
42-
const timer = setTimeout(() => {
43-
const body = {
44-
q: q,
45-
top: 5,
46-
suggester: 'sg'
47-
};
4832

49-
if (q === '') {
50-
setSuggestions([]);
51-
} else {
52-
axios.post( '/api/suggest', body)
53-
.then(response => {
54-
console.log(JSON.stringify(response.data))
55-
setSuggestions(response.data.suggestions);
56-
} )
57-
.catch(error => {
58-
console.log(error);
59-
setSuggestions([]);
60-
});
61-
}
62-
}, 300);
63-
return () => clearTimeout(timer);
64-
}, [q, props]);
33+
const onChangeHandler = (event, value) => {
34+
console.log(`onChangeHandler: ${value}`);
35+
setQ(value);
36+
search(value);
37+
};
6538

66-
var suggestionDiv;
67-
if (showSuggestions) {
68-
suggestionDiv = (<Suggestions suggestions={suggestions} suggestionClickHandler={(s) => suggestionClickHandler(s)}></Suggestions>);
69-
} else {
70-
suggestionDiv = (<div></div>);
39+
const onEnterButton = (event) => {
40+
console.log(`onEnterButton: ${q}`);
41+
// if enter key is pressed
42+
if (event.key === 'Enter') {
43+
search(q);
7144
}
45+
};
7246

73-
return (
74-
<div >
75-
<div className="input-group" onKeyDown={e => onEnterButton(e)}>
76-
<div className="suggestions" >
77-
<input
78-
autoComplete="off" // setting for browsers; not the app
79-
type="text"
80-
id="search-box"
81-
className="form-control rounded-0"
82-
placeholder="What are you looking for?"
83-
onChange={onChangeHandler}
84-
defaultValue={props.q}
85-
onBlur={() => setShowSuggestions(false)}
86-
onClick={() => setShowSuggestions(true)}>
87-
</input>
88-
{suggestionDiv}
89-
</div>
90-
<div className="input-group-btn">
91-
<button className="btn btn-primary rounded-0" type="submit" onClick={onSearchHandler}>
92-
Search
93-
</button>
94-
</div>
95-
</div>
96-
</div>
97-
);
98-
};
47+
return (
48+
<div
49+
className="input-group"
50+
style={{ width: '95%', display: 'flex', justifyContent: 'center', alignItems: 'center', margin: '0 auto' }}
51+
>
52+
<Box sx={{ display: 'flex', alignItems: 'center', width: '75%', minWidth: '390px' }}>
53+
<Autocomplete
54+
freeSolo
55+
value={q}
56+
options={suggestions}
57+
onInputChange={onInputChangeHandler}
58+
onChange={onChangeHandler}
59+
disableClearable
60+
sx={{
61+
width: '75%',
62+
'& .MuiAutocomplete-endAdornment': {
63+
display: 'none'
64+
}
65+
}}
66+
renderInput={(params) => (
67+
<TextField
68+
{...params}
69+
id="search-box"
70+
className="form-control rounded-0"
71+
placeholder="What are you looking for?"
72+
onBlur={() => setSuggestions([])}
73+
onClick={() => setSuggestions([])}
74+
/>
75+
)}
76+
/>
77+
<div className="input-group-btn" style={{ marginLeft: '10px' }}>
78+
<Button variant="contained" color="primary" onClick={() => {
79+
console.log(`search button: ${q}`);
80+
search(q)}
81+
}>
82+
Search
83+
</Button>
84+
</div>
85+
</Box>
86+
</div>
87+
);
88+
}

client/src/components/SearchBar/Suggestions/Suggestions.css

Lines changed: 0 additions & 6 deletions
This file was deleted.

client/src/components/SearchBar/Suggestions/Suggestions.js

Lines changed: 0 additions & 27 deletions
This file was deleted.

client/src/pages/Home/Home.css

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,24 @@
11
.home-search {
22
margin: 5em auto;
3-
max-width: 45%;
4-
display: block;
3+
display: flex;
4+
flex-direction: column;
5+
align-items: center; /* Center child elements horizontally */
6+
}
7+
8+
.center-container {
9+
display: flex;
10+
justify-content: center;
11+
align-items: center;
12+
margin-top: 5em;
513
}
614

715
.logo {
816
height: 12em;
917
width: auto;
10-
display:block;
18+
display: block;
1119
margin: auto auto 0;
20+
object-fit: contain; /* Ensures the image maintains its aspect ratio */
21+
max-width: 100%; /* Prevents the image from exceeding the container's width */
1222
}
1323

1424
.poweredby {

client/src/pages/Home/Home.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ export default function Home() {
1717
}
1818

1919
return (
20+
<div className="center-container">
2021
<main className="main main--home">
2122
<div className="row home-search">
2223
<img className="logo" src={logo} alt="Cognitive Search"></img>
2324
<p className="poweredby lead">Powered by Azure AI Search</p>
2425
<SearchBar postSearchHandler={navigateToSearchPage}></SearchBar>
2526
</div>
2627
</main>
28+
</div>
2729
);
2830
};

client/src/pages/Search/Search.css

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
.main--search {
2+
display: flex;
3+
flex-direction: column;
4+
}
5+
.row {
6+
display: flex;
7+
flex-wrap: wrap;
8+
}
9+
10+
.search-bar-column {
11+
flex: 1;
12+
min-width: 300px; /* Adjust as needed */
13+
}
14+
15+
.search-bar-results {
16+
flex: 2;
17+
min-width: 300px; /* Adjust as needed */
18+
}
19+
20+
@media (max-width: 768px) {
21+
.row {
22+
flex-direction: column;
23+
}
24+
25+
}
26+
27+
128
.sui-layout-header {
229
background-color: #0078d7;
330
color: #eee;

client/src/pages/Search/Search.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React, { useEffect, useState, Suspense } from 'react';
22
import axios from '../../axios.js';
33
import CircularProgress from '@mui/material/CircularProgress';
44
import { useLocation, useNavigate } from "react-router-dom";
@@ -76,7 +76,7 @@ export default function Search() {
7676
} else {
7777
body = (
7878
<div className="col-md-9">
79-
<Results documents={results} top={top} skip={skip} count={resultCount}></Results>
79+
<Results documents={results} top={top} skip={skip} count={resultCount} query={q}></Results>
8080
<Pager className="pager-style" currentPage={currentPage} resultCount={resultCount} resultsPerPage={resultsPerPage} setCurrentPage={setCurrentPage}></Pager>
8181
</div>
8282
)
@@ -98,9 +98,9 @@ export default function Search() {
9898
<main className="main main--search container-fluid">
9999

100100
<div className="row">
101-
<div className="col-md-3">
101+
<div className="search-bar-column col-md-3">
102102
<div className="search-bar">
103-
<SearchBar postSearchHandler={postSearchHandler} q={q}></SearchBar>
103+
<SearchBar postSearchHandler={postSearchHandler} query={q}></SearchBar>
104104
</div>
105105
<Facets facets={facets} filters={filters} setFilters={updateFilterHandler}></Facets>
106106
</div>

0 commit comments

Comments
 (0)