Skip to content

Commit

Permalink
Merge pull request #3820 from ivanko22/searchBox2024
Browse files Browse the repository at this point in the history
update SearchBar into SearchBar2024
  • Loading branch information
DaleMcGrew authored Feb 1, 2024
2 parents 31b5728 + 670d502 commit 18a3012
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 60 deletions.
16 changes: 3 additions & 13 deletions src/js/components/CampaignsHome/CampaignsHomeFilter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,15 @@ import PropTypes from 'prop-types';
import React from 'react';
import styled from 'styled-components';
import { renderLog } from '../../common/utils/logging';
import { SearchTitleTop } from '../../common/components/Style/FilterStyles';
import StateDropDownCore from '../Filter/StateDropDownCore';
import SearchBar from '../Search/SearchBar';
import BaseSearchbox from '../../../js/components/Search/BaseSearchbox';
import SearchBar2024 from '../Search/SearchBar2024';

// React functional component example
function CampaignsHomeFilter (props) {
renderLog('CampaignsHomeFilter functional component');
const { classes, isSearching, listModeFiltersAvailable, searchText, stateCode } = props;
const { classes, listModeFiltersAvailable, stateCode } = props;
// console.log('CampaignsHomeFilter props.listModeFiltersAvailable:', props.listModeFiltersAvailable);
return (
<CampaignsHomeFilterWrapper>
{/* {(isSearching && searchText) && (
<SearchTitleTop>
Searching for &quot;
{searchText}
&quot;
</SearchTitleTop>
)} */}
{!!(listModeFiltersAvailable) && (
<CampaignsHomeFilterChoices>
{listModeFiltersAvailable.map((oneFilter) => (
Expand All @@ -48,7 +38,7 @@ function CampaignsHomeFilter (props) {
</CampaignsHomeFilterChoices>
)}
<SearchBarWrapper>
<SearchBar
<SearchBar2024
clearButton
searchButton
placeholder="Search by name, office or state"
Expand Down
9 changes: 7 additions & 2 deletions src/js/components/CandidateListRoot/CandidateListRoot.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ class CandidateListRoot extends Component {
}

componentDidMount () {
// console.log('CandidateListRoot componentDidMount');
this.candidateStoreListener = CandidateStore.addListener(this.onCandidateStoreChange.bind(this));
const { incomingList } = this.props;
// console.log('CandidateListRoot componentDidMount incomingList:', incomingList);
Expand Down Expand Up @@ -158,7 +157,6 @@ class CandidateListRoot extends Component {
orderByUltimateElectionDate = (firstEntry, secondEntry) => secondEntry.candidate_ultimate_election_date - firstEntry.candidate_ultimate_election_date;

onFilterOrListChange = () => {
// console.log('onFilterOrListChange');
// Start over with full list, and apply all active filters
const { listModeFilters, searchText, stateCode } = this.props;
const { candidateList } = this.state;
Expand Down Expand Up @@ -257,6 +255,7 @@ class CandidateListRoot extends Component {
filteredList = filteredList.sort(this.orderByUltimateElectionDate);
let searchResults = [];
let hideDisplayBecauseNoSearchResults = false;
this.callbackToParentHideIfNoResults(false);
if (searchText && searchText.length > 0) {
const searchTextLowercase = searchText.toLowerCase();
// console.log('searchTextLowercase:', searchTextLowercase);
Expand Down Expand Up @@ -289,6 +288,7 @@ class CandidateListRoot extends Component {
});
if (searchResults.length === 0) {
hideDisplayBecauseNoSearchResults = true;
this.callbackToParentHideIfNoResults(true);
}
if (searchResults.length > 0) {
// Only allow the first politician entry to be displayed (when there are multiple candidate entries for the same politician)
Expand Down Expand Up @@ -351,6 +351,10 @@ class CandidateListRoot extends Component {
});
}

callbackToParentHideIfNoResults = (newValue) => {
this.props.onHideIfNoResultsChange(newValue);
}

render () {
renderLog('CandidateListRoot'); // Set LOG_RENDER_EVENTS to log all renders
const { classes, hideIfNoResults, hideTitle, searchText, titleTextForList } = this.props;
Expand Down Expand Up @@ -435,6 +439,7 @@ class CandidateListRoot extends Component {
CandidateListRoot.propTypes = {
classes: PropTypes.object,
hideIfNoResults: PropTypes.bool,
onHideIfNoResultsChange: PropTypes.func,
hideTitle: PropTypes.bool,
incomingList: PropTypes.array,
incomingListTimeStampOfChange: PropTypes.number,
Expand Down
54 changes: 27 additions & 27 deletions src/js/components/Search/BaseSearchbox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,58 +65,58 @@ const SearchInput = styled.input`
`;

class BaseSearchbox extends React.Component {
constructor(props) {
constructor (props) {
super(props);
this.state = { searchText: '' };
}

handleInputChange = (event) => {
this.setState({ searchText: event.target.value }, () => {
if (this.props.onChange) {
this.props.onChange(event);
}
if (this.props.onKeyDown) {
this.props.onKeyDown(event);
}
if(this.props.onFocus) {
this.props.onFocus(event);
}
if (this.props.onChange) {
this.props.onChange(event);
}
if (this.props.onKeyDown) {
this.props.onKeyDown(event);
}
if (this.props.onFocus) {
this.props.onFocus(event);
}
});
}

handleClear = () => {
this.setState({ searchText: '' }, () => {
if (this.props.onClear) {
this.props.onClear();
}
if (this.props.onClear) {
this.props.onClear();
}
});
}

render() {
render () {
return (
<SearchWrapper>
{!this.state.searchText && <SearchIcon />}
<SearchInput
type="search"
placeholder={this.props.placeholder}
value={this.state.searchText}
onChange={this.handleInputChange}
<SearchInput
type="search"
placeholder={this.props.placeholder}
value={this.state.searchText}
onChange={this.handleInputChange}
onClear={this.handleClear}
maxLength={50}
/>
{this.state.searchText && <ClearButton onClick={this.handleClear}/>}
{this.state.searchText && <ClearButton onClick={this.handleClear} />}
</SearchWrapper>
);
}
}

BaseSearchbox.propTypes = {
placeholder: PropTypes.string,
onChange: PropTypes.func,
onKeyDown: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
onClear: PropTypes.func,
placeholder: PropTypes.string,
onChange: PropTypes.func,
onKeyDown: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
onClear: PropTypes.func,
};

export default BaseSearchbox;
export default BaseSearchbox;
40 changes: 34 additions & 6 deletions src/js/components/Search/SearchBar.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { CancelOutlined, Search } from '@mui/icons-material';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import styled from 'styled-components';
import { blurTextFieldAndroid, focusTextFieldAndroid, isIPhoneMiniOrSmaller } from '../../common/utils/cordovaUtils';
import { renderLog } from '../../common/utils/logging';

import BaseSearchbox from '../Search/BaseSearchbox';

/* eslint-disable jsx-a11y/control-has-associated-label */

export default class SearchBar extends Component {
constructor (props) {
super(props);
Expand All @@ -21,6 +21,7 @@ export default class SearchBar extends Component {
}

componentDidMount () {
// console.log("SearchBar, this.props.clearSearchTextNow:", this.props.clearSearchTextNow);
if (this.props.clearSearchTextNow) {
if (this.props.clearFunction) {
this.props.clearFunction();
Expand Down Expand Up @@ -78,20 +79,43 @@ export default class SearchBar extends Component {

render () {
renderLog('SearchBar'); // Set LOG_RENDER_EVENTS to log all renders
const { placeholder } = this.props;
const { clearButton, placeholder, searchButton } = this.props;
const { searchString } = this.state;
return (
<div className="search-bar clearfix">
<BaseSearchbox
<SearchInput
id="search_input"
type="text"
className="form-control"
placeholder={placeholder}
value={searchString}
onKeyDown={this.handleKeyPress}
onChange={this.updateResults}
onFocus={() => focusTextFieldAndroid('SearchBar')}
onBlur={blurTextFieldAndroid}
onClear={this.clearQuery}
onBlur={blurTextFieldAndroid}
/>
<div className="search-bar-options">
{(clearButton && searchString && searchString.length > 0) && (
<button
className="search-clear-btn"
onClick={this.clearQuery}
type="button"
id="search-clear"
>
<CancelOutlined />
</button>
)}
{(searchButton) && (
<button
className="search-options-btn"
type="button"
id="search"
style={{ paddingLeft: 0 }}
>
<Search />
</button>
)}
</div>
</div>
);
}
Expand All @@ -105,3 +129,7 @@ SearchBar.propTypes = {
searchFunction: PropTypes.func.isRequired,
searchUpdateDelayTime: PropTypes.number.isRequired,
};

const SearchInput = styled('input')`
${isIPhoneMiniOrSmaller() ? 'font-size: 0.8rem' : ''};
`;
107 changes: 107 additions & 0 deletions src/js/components/Search/SearchBar2024.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { blurTextFieldAndroid, focusTextFieldAndroid } from '../../common/utils/cordovaUtils';
import { renderLog } from '../../common/utils/logging';
import BaseSearchbox from './BaseSearchbox';

/* eslint-disable jsx-a11y/control-has-associated-label */
export default class SearchBar2024 extends Component {
constructor (props) {
super(props);

this.state = {
searchString: '',
};

this.handleKeyPress = this.handleKeyPress.bind(this);
this.updateResults = this.updateResults.bind(this);
this.clearQuery = this.clearQuery.bind(this);
}

componentDidMount () {
if (this.props.clearSearchTextNow) {
if (this.props.clearFunction) {
this.props.clearFunction();
}
const { searchString } = this.state;
if (searchString) {
this.setState({
searchString: '',
});
}
}
}

componentDidUpdate (prevProps) {
if (this.props.clearSearchTextNow !== prevProps.clearSearchTextNow) {
if (this.props.clearSearchTextNow) {
if (this.props.clearFunction) {
this.props.clearFunction();
}
const { searchString } = this.state;
if (searchString) {
this.setState({
searchString: '',
});
}
}
}
}

componentWillUnmount () {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}

handleKeyPress () {
if (this.timer) clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.props.searchFunction(this.state.searchString);
}, this.props.searchUpdateDelayTime);
}

clearQuery () {
this.props.clearFunction();
this.setState({ searchString: '' });
}

updateResults (event) {
const searchString = event.target.value;
this.setState({
searchString,
});
}

// check limit of 50 characters
render () {
renderLog('SearchBar2024'); // Set LOG_RENDER_EVENTS to log all renders
const { placeholder } = this.props;
const { searchString } = this.state;
return (
<div className="search-bar clearfix">
<BaseSearchbox
id="search_input"
placeholder={placeholder}
value={searchString}
onKeyDown={this.handleKeyPress}
onChange={this.updateResults}
onFocus={() => focusTextFieldAndroid('SearchBar2024')}
onBlur={blurTextFieldAndroid}
onClear={this.clearQuery}
/>
</div>
);
}
}

SearchBar2024.propTypes = {
clearButton: PropTypes.bool,
clearFunction: PropTypes.func.isRequired,
clearSearchTextNow: PropTypes.bool,
placeholder: PropTypes.string,
searchButton: PropTypes.bool,
searchFunction: PropTypes.func.isRequired,
searchUpdateDelayTime: PropTypes.number.isRequired,
};
Loading

0 comments on commit 18a3012

Please sign in to comment.