react-use#useDebounce JavaScript Examples
The following examples show how to use
react-use#useDebounce.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: useCalculation.js From Turnip-Calculator with MIT License | 6 votes |
useCalculation = ({ filters, immediate = false }) => {
const [state, setState] = useState(null);
const [quantileRange] = useContext(QuantileContext);
useDebounce(
() => {
if (filters) {
calculate({ filters, quantileRange })
.then(setState)
.catch(() => setState(null));
} else {
setState(null);
}
},
immediate ? 0 : 500,
[filters, quantileRange]
);
const { minMaxPattern, minWeekValue, patterns, quantiles } = state || {};
return useMemo(
() => ({ minMaxPattern, minWeekValue, patterns, quantiles, filters }),
// eslint-disable-next-line react-hooks/exhaustive-deps
[state]
);
}
Example #2
Source File: resources.js From covid19Nepal-react with MIT License | 4 votes |
function Resources(props) {
const [data, setData] = useState([]);
const [partData, setPartData] = useState([]);
const [ogData, setOgData] = useState([]);
const [fetched, setFetched] = useState(false);
const [city, setCity] = useState('all');
const [category, setCategory] = useState('all');
const [nepalstate, setNepalState] = useState('all');
const [resourcedict, setResourceDict] = useState({});
const [showTable, setShowTable] = useState(false);
const [isDesktop, setIsDesktop] = useState(false);
const [hasScrolled, setHasScrolled] = useState(false);
const [anchorEl, setAnchorEl] = React.useState(null);
const [searchValue, setSearchValue] = useState('');
useEffect(() => {
if (fetched === false) {
getResources();
}
}, [fetched, data, resourcedict]);
const checkForResizeEvent = useCallback((event) => {
if (window.innerWidth > 639) setIsDesktop(true);
else setIsDesktop(false);
}, []);
useEffect(() => {
if (window.innerWidth > 639) setIsDesktop(true);
else setIsDesktop(false);
window.addEventListener('resize', checkForResizeEvent);
return () => {
window.removeEventListener('resize', checkForResizeEvent);
};
}, [isDesktop, checkForResizeEvent]);
const checkScrollEvent = useCallback((event) => {
window.pageYOffset > 100 ? setHasScrolled(true) : setHasScrolled(false);
}, []);
useEffect(() => {
window.pageYOffset > 100 ? setHasScrolled(true) : setHasScrolled(false);
window.addEventListener('scroll', checkScrollEvent);
return () => {
window.removeEventListener('scroll', checkScrollEvent);
};
}, [hasScrolled, checkScrollEvent]);
const getResources = async () => {
try {
const [response] = await Promise.all([
axios.get('https://api.nepalcovid19.org/resources/resources.json'),
]);
// setData(response.data.resources);
const hashmap = {};
response.data.resources.forEach((x) => {
if (typeof hashmap[x['state']] === 'undefined')
hashmap[x['state']] = {};
if (typeof hashmap[x['state']][x['city']] === 'undefined')
hashmap[x['state']][x['city']] = {};
if (
typeof hashmap[x['state']][x['city']][x['category']] === 'undefined'
)
hashmap[x['state']][x['city']][x['category']] = [];
if (Array.isArray(hashmap[x['state']][x['city']][x['category']]))
hashmap[x['state']][x['city']][x['category']].push(x);
});
setResourceDict(hashmap);
setFetched(true);
} catch (err) {}
};
const handleDisclaimerClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleDisclaimerClose = () => {
setAnchorEl(null);
};
const isDisclaimerOpen = Boolean(anchorEl);
const id = isDisclaimerOpen ? 'simple-popover' : undefined;
function animateScroll() {
document.body.scrollTo({top: 0, behavior: 'smooth'}); // For Safari
document.documentElement.scrollTo({top: 0, behavior: 'smooth'}); // For Chrome, Firefox, IE and Opera
}
const memocols = React.useMemo(
() => [
{
Header: 'City',
accessor: 'city',
},
{
Header: 'Category',
accessor: 'category',
},
{
Header: 'Organisation',
accessor: 'nameoftheorganisation',
},
{
Header: 'Description',
accessor: 'descriptionandorserviceprovided',
},
{
Header: 'Phone',
accessor: 'phonenumber',
},
{
Header: 'Source',
accessor: 'contact',
isVisible: false,
},
],
[]
);
// const memodata = React.useMemo(() => data, [data])
const getCityOptions = function () {
if (nepalstate) {
if (nepalstate === 'all') return [];
else {
return Object.keys(resourcedict[nepalstate])
.sort()
.map((x, i) => (
<option
key={i}
value={x}
style={{
fontFamily: 'archia',
fontSize: '11px !important',
fontWeight: 600,
textTransform: 'uppercase',
}}
>
{x}
</option>
));
}
} else return [];
// return getCityList().map((x) => <option value={x}>{x}</option>)
};
const getnepalstateOptions = function () {
// let defaultOption = ['Please select']
return Object.keys(resourcedict)
.sort()
.map((x, i) => (
<option
key={i}
value={x}
style={{
fontFamily: 'archia',
fontSize: '11px !important',
fontWeight: 600,
textTransform: 'uppercase',
}}
>
{x}
</option>
));
};
const getCategoryOptions = function () {
if (nepalstate && city) {
if (nepalstate === 'all') {
const array = [];
Object.values(resourcedict).forEach((state) => {
Object.values(state).forEach((citydata) => {
Object.keys(citydata).forEach((x) => {
if (array.indexOf(x) === -1) array.push(x);
});
});
});
return array.sort().map((x, i) => (
<option
key={i}
value={x}
style={{
fontFamily: 'archia',
fontSize: '11px !important',
fontWeight: 600,
textTransform: 'uppercase',
}}
>
{x}
</option>
));
} else {
if (city === 'all') {
const array = [];
Object.values(resourcedict[nepalstate]).forEach((citydata) => {
Object.keys(citydata).forEach((x) => {
if (array.indexOf(x) === -1) array.push(x);
});
});
return array.sort().map((x, i) => (
<option
key={i}
value={x}
style={{
fontFamily: 'archia',
fontSize: '11px !important',
fontWeight: 600,
textTransform: 'uppercase',
}}
>
{x}
</option>
));
} else {
return Object.keys(resourcedict[nepalstate][city])
.sort()
.map((x, i) => (
<option
key={i}
value={x}
style={{
fontFamily: 'archia',
fontSize: '11px !important',
fontWeight: 600,
textTransform: 'uppercase',
}}
>
{x}
</option>
));
}
}
} else return [];
};
const filterTable = function () {
let a = [];
if (category === 'all') {
if (city === 'all') {
if (nepalstate === 'all') {
Object.values(resourcedict).forEach((state) => {
Object.values(state).forEach((citydata) => {
Object.values(citydata).forEach((category) => {
category.forEach((x) => a.push(x));
});
});
});
} else {
Object.values(resourcedict[nepalstate]).forEach((citydata) => {
Object.values(citydata).forEach((category) => {
category.forEach((x) => a.push(x));
});
});
}
} else {
Object.values(resourcedict[nepalstate][city]).forEach((x) => {
x.forEach((y) => a.push(y));
});
}
} else {
if (nepalstate === 'all' && city === 'all') {
Object.values(resourcedict).forEach((state) => {
Object.values(state).forEach((citydata) => {
Object.values(citydata).forEach((categorydata) => {
categorydata.forEach((x) => {
if (x.category === category) a.push(x);
});
});
});
});
} else if (nepalstate !== 'all' && city === 'all') {
Object.values(resourcedict[nepalstate]).forEach((citydata) => {
if (category in citydata) {
citydata[category].forEach((x) => {
a.push(x);
});
}
});
} else {
a = resourcedict[nepalstate][city][category];
}
}
try {
if ('PAN Nepal' in resourcedict) {
resourcedict['PAN Nepal']['Multiple']['CoVID-19 Testing Lab'].forEach(
(element) => {
a.push(element);
}
);
}
} catch (err) {}
setData(a);
setOgData(a);
setPartData(a.slice(0, 30));
setShowTable(true);
try {
document.getElementById('input-field-searchbar').value = '';
} catch {}
setSearchValue('');
};
const changeNepalState = function (changedstateevent) {
setNepalState(changedstateevent.target.value);
// setCity(
// Object.keys(resourcedict[changedstateevent.target.value]).sort()[0]
// );
if (changedstateevent.target.value === '') {
setCity('');
document.getElementById('cityselect1').selectedIndex = 0;
setCategory('');
document.getElementById('categoryselect').selectedIndex = 0;
} else {
setCity('all');
document.getElementById('cityselect1').selectedIndex = 1;
setCategory('all');
document.getElementById('categoryselect').selectedIndex = 1;
}
};
const changeCity = function (changedcityevent) {
setCity(changedcityevent.target.value);
setCategory('all');
document.getElementById('categoryselect').selectedIndex = 1;
};
const changeCategory = function (changedcategoryevent) {
setCategory(changedcategoryevent.target.value);
};
const appendData = function () {
const tempArr = partData.concat(
data.slice(partData.length, partData.length + 30)
);
setPartData(tempArr);
};
const openSharingLink = function (message) {
const shareUri = `https://www.addtoany.com/share#url=${encodeURI(
'https://www.nepalcovid19.org/essentials'
)}&title=${encodeURI(message)}`;
const h = 500;
const w = 500;
const left = window.screen.width / 2 - w / 2;
const top = window.screen.height / 2 - h / 2;
return window.open(
shareUri,
document.title,
'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=' +
w +
', height=' +
h +
', top=' +
top +
', left=' +
left
);
};
const openSharingTray = function () {
const message =
'Discover nearest coronavirus support and essential service providers such as testing lab centres, accommodation shelters and vegetable vendors at ';
if (navigator.share !== undefined) {
navigator
.share({
title: document.title,
text: message,
url: 'https://www.nepalcovid19.org/essentials',
})
.then()
.catch((error) => {});
} else {
openSharingLink(message);
}
};
useDebounce(
() => {
const newData = getSuggestions(searchValue, ogData);
setData(newData);
setPartData(newData.slice(0, 30));
},
300,
[searchValue, ogData]
);
return (
<div className="Resources" id="top-elem">
<Helmet>
<title>Essentials - nepalcovid19.org</title>
<meta name="title" content="Essentials - nepalcovid19.org" />
</Helmet>
<div className="filtersection">
<div className="filtertitle">
<h3>Service Before Self</h3>
</div>
{!isDesktop && (
<FiltersMobile
handleDisclaimerClick={handleDisclaimerClick}
popoverid={id}
isDisclaimerOpen={isDisclaimerOpen}
anchorEl={anchorEl}
handleDisclaimerClose={handleDisclaimerClose}
nepalstate={nepalstate}
changeNepalState={changeNepalState}
stateoptions={getnepalstateOptions()}
city={city}
changeCity={changeCity}
cityoptions={getCityOptions()}
category={category}
changeCategory={changeCategory}
servicesoptions={getCategoryOptions()}
filterTable={filterTable}
openSharingTray={openSharingTray}
/>
)}
{isDesktop && (
<FiltersDesktop
handleDisclaimerClick={handleDisclaimerClick}
popoverid={id}
isDisclaimerOpen={isDisclaimerOpen}
anchorEl={anchorEl}
handleDisclaimerClose={handleDisclaimerClose}
nepalstate={nepalstate}
changeNepalState={changeNepalState}
stateoptions={getnepalstateOptions()}
city={city}
changeCity={changeCity}
cityoptions={getCityOptions()}
category={category}
changeCategory={changeCategory}
servicesoptions={getCategoryOptions()}
filterTable={filterTable}
openSharingTray={openSharingTray}
/>
)}
</div>
{showTable && (
<React.Fragment>
<div className="searchbar">
<TextField
id="input-field-searchbar"
label="Search keyword"
fullWidth={true}
InputLabelProps={{
shrink: true,
}}
style={{
width: '100%',
}}
variant="outlined"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Icon.Search size="0.9em" />
</InputAdornment>
),
}}
onChange={(event) => {
setInterval(setSearchValue(event.target.value));
}}
/>
</div>
<ResourceTable
columns={memocols}
data={partData}
totalCount={data.length}
isDesktop={isDesktop}
onScrollUpdate={appendData}
searchValue={searchValue}
/>
<div>
<Fade in={hasScrolled}>
<Fab
color="inherit"
aria-label="gototop"
id="gototopbtn"
onClick={animateScroll}
size="small"
style={{
position: 'fixed',
bottom: '1rem',
right: '1rem',
zIndex: '1000',
}}
>
<Icon.Navigation2 strokeWidth="2.5" color="#4c75f2" />
</Fab>
</Fade>
</div>
</React.Fragment>
)}
</div>
);
}
Example #3
Source File: search.js From covid19Nepal-react with MIT License | 4 votes |
function Search({districtZones}) {
const [searchValue, setSearchValue] = useState('');
const [expand, setExpand] = useState(false);
const [results, setResults] = useState([]);
const searchInput = useRef(null);
const {t} = useTranslation();
const handleSearch = useCallback((searchInput) => {
const results = [];
const sync = (datums) => {
datums.map((result, index) => {
const stateObj = {
name: result.name,
type: 'state',
route: result.code,
};
results.push(stateObj);
return null;
});
};
const districtSync = (datums) => {
datums.slice(0, 3).map((result, index) => {
const districtObj = {
name: result.district,
type: 'district',
route: STATE_CODES_REVERSE[result.state],
};
results.push(districtObj);
return null;
});
};
const essentialsSync = (datums) => {
datums.slice(0, 5).map((result, index) => {
const essentialsObj = {
name: result.nameoftheorganisation,
type: 'essentials',
category: result.category,
website: result.contact,
description: result.descriptionandorserviceprovided,
city: result.city,
state: result.state,
contact: result.phonenumber,
};
results.push(essentialsObj);
return null;
});
setResults([...results]);
};
engine.search(searchInput, sync);
districtEngine.search(searchInput, districtSync);
essentialsEngine.search(searchInput, essentialsSync);
}, []);
useDebounce(
() => {
if (searchValue) {
handleSearch(searchValue);
} else {
setResults([]);
}
},
100,
[searchValue]
);
function setNativeValue(element, value) {
const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
const prototype = Object.getPrototypeOf(element);
const prototypeValueSetter = Object.getOwnPropertyDescriptor(
prototype,
'value'
).set;
if (valueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {
valueSetter.call(element, value);
}
}
function fillPlaceholder(target, index, cursorPosition, callback) {
if (focused) {
target.textContent = '';
return true;
}
const text = suggestions[index];
const placeholder = target.textContent;
target.classList.remove('disappear');
target.textContent = placeholder + text[cursorPosition];
if (cursorPosition < text.length - 1) {
setTimeout(function () {
fillPlaceholder(target, index, cursorPosition + 1, callback);
}, 200);
return true;
}
callback();
}
function clearPlaceholder(target, callback) {
const placeholder = target.textContent;
target.classList.add('disappear');
if (placeholder.length > 0) {
setTimeout(function () {
target.textContent = '';
clearPlaceholder(target, callback);
}, 1000);
return true;
}
callback();
}
function loopThroughSuggestions(target, index) {
if (focused) {
target.textContent = '';
return true;
}
fillPlaceholder(target, index, 0, function () {
setTimeout(function () {
clearPlaceholder(target, function () {
loopThroughSuggestions(target, (index + 1) % suggestions.length);
});
}, 2000);
});
}
const targetInput = document.getElementById('search-placeholder');
if (targetInput) loopThroughSuggestions(targetInput, 0);
return (
<div className="Search">
<label>{t('Search your district, resources, etc')}</label>
<div className="line"></div>
<input
type="text"
value={searchValue}
ref={searchInput}
onFocus={(event) => {
focused = true;
setExpand(true);
}}
onBlur={() => {
setExpand(false);
}}
onChange={(event) => {
setSearchValue(event.target.value);
}}
/>
<span id="search-placeholder" className="search-placeholder"></span>
<div className={`search-button`}>
<Icon.Search />
</div>
{searchValue.length > 0 && (
<div
className={`close-button`}
onClick={() => {
setSearchValue('');
setResults([]);
}}
>
<Icon.X />
</div>
)}
{results.length > 0 && (
<div className="results">
{results.map((result, index) => {
if (result.type === 'state' || result.type === 'district') {
return (
<Link key={index} to={`state/${result.route}`}>
<div className="result">
<div className="result-left">
<div className="result-name">
{`${result.name}`}
{result.type === 'district' &&
`, ${STATE_CODES[result.route]}`}
</div>
<div
className={classnames('result-zone', {
[`is-${districtZones[STATE_CODES[result.route]][
result.name
]?.zone.toLowerCase()}`]: true,
})}
></div>
</div>
<div className="result-type">
<span>{[result.route]}</span>
<Icon.ArrowRightCircle size={14} />
</div>
</div>
</Link>
);
} else {
return (
<a
key={index}
href={result.website}
target="_noblank"
className="essential-result"
>
<div className="result-top">
<div className="result-top-left">
<div className="result-name">{result.name}</div>
<div className="result-location">
{result.city}, {result.state}
</div>
</div>
<div className="result-category">
<div>
{result.category.match('Testing')
? 'Covid19-Testing Labs'
: result.category}
</div>
<Icon.ExternalLink />
</div>
</div>
<div className="result-description">{result.description}</div>
<div className="result-contact">
<Icon.Phone />
<div>{result.contact}</div>
</div>
</a>
);
}
})}
</div>
)}
{expand && (
<div className="expanded">
<div className="expanded-left">
<h3>{t('Essentials')}</h3>
<div className="suggestions">
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, 'Covid19-Testing Labs');
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t('Covid19-Testing Labs')}
</h4>
</div>
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, 'Quarantine Center');
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t('Quarantine Center')}
</h4>
</div>
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, 'Health Facility');
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t('Health Facility')}
</h4>
</div>
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, 'Medical College');
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t('Medical College')}
</h4>
</div>
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(
searchInput.current,
' District Level Hospital'
);
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t(' District Level Hospital')}
</h4>
</div>
</div>
</div>
<div className="expanded-right">
<h3>{t('Locations')}</h3>
<div className="suggestions">
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, 'Kathmandu');
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t('Kathmandu')}
</h4>
</div>
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, 'Rautahat');
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t('Rautahat')}
</h4>
</div>
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, 'Chitwan');
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t('Chitwan')}
</h4>
</div>
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, 'Baglung');
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t('Baglung')}
</h4>
</div>
<div className="suggestion">
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, 'Udayapur');
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t('Udayapur')}
</h4>
</div>
</div>
</div>
</div>
)}
</div>
);
}
Example #4
Source File: Search.js From covid19india-react with MIT License | 4 votes |
function Search() {
const [searchValue, setSearchValue] = useState('');
const [expand, setExpand] = useState(false);
const [results, setResults] = useState([]);
const searchInput = useRef(null);
const {t} = useTranslation();
const [engine, setEngine] = useState(null);
const [districtEngine, setDistrictEngine] = useState(null);
useUpdateEffect(() => {
import('corejs-typeahead').then((Bloodhound) => {
setEngine(
// eslint-disable-next-line
new Bloodhound.default({
initialize: true,
local: STATE_CODES_ARRAY.filter(
({code}) => code !== UNASSIGNED_STATE_CODE
),
queryTokenizer: Bloodhound.default.tokenizers.whitespace,
datumTokenizer: Bloodhound.default.tokenizers.obj.whitespace('name'),
})
);
setDistrictEngine(
// eslint-disable-next-line
new Bloodhound.default({
initialize: true,
limit: 5,
queryTokenizer: Bloodhound.default.tokenizers.whitespace,
datumTokenizer:
Bloodhound.default.tokenizers.obj.whitespace('district'),
indexRemote: true,
remote: {
url: `${API_DOMAIN}/state_district_wise.json`,
transform: function (response) {
const districts = [];
Object.keys(response)
.filter((stateName) => stateName !== 'State Unassigned')
.map((stateName) => {
const districtData = response[stateName].districtData;
Object.keys(districtData)
.filter(
(districtName) => districtName !== UNKNOWN_DISTRICT_KEY
)
.map((districtName) => {
return districts.push({
district: districtName,
state: stateName,
});
});
return null;
});
return districts;
},
},
})
);
});
}, [expand]);
const handleSearch = useCallback(
(searchInput) => {
if (!engine) return null;
const results = [];
const sync = (datums) => {
datums.map((result, index) => {
const stateObj = {
name: result.name,
type: 'state',
route: result.code,
};
results.push(stateObj);
return null;
});
};
const districtSync = (datums) => {
datums.slice(0, 3).map((result, index) => {
const districtObj = {
name: result.district,
type: 'district',
route: STATE_CODES[result.state],
};
results.push(districtObj);
return null;
});
setResults([...results]);
};
engine.search(searchInput, sync);
districtEngine.search(searchInput, districtSync);
},
[districtEngine, engine]
);
useDebounce(
() => {
if (searchValue) {
handleSearch(searchValue);
} else {
setResults(
produce(results, (draftResults) => {
draftResults.splice(0);
})
);
}
},
100,
[searchValue]
);
function setNativeValue(element, value) {
const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
const prototype = Object.getPrototypeOf(element);
const prototypeValueSetter = Object.getOwnPropertyDescriptor(
prototype,
'value'
).set;
if (valueSetter && valueSetter !== prototypeValueSetter) {
prototypeValueSetter.call(element, value);
} else {
valueSetter.call(element, value);
}
}
const fillPlaceholder = useCallback(
(target, index, cursorPosition, callback) => {
if (expand) {
target.textContent = '';
return true;
}
const text = t(suggestions[index]);
const placeholder = target.textContent;
target.classList.remove('disappear');
target.textContent = placeholder + text[cursorPosition];
if (cursorPosition < text.length - 1) {
setTimeout(function () {
fillPlaceholder(target, index, cursorPosition + 1, callback);
}, 200);
return true;
}
callback();
},
[expand, t]
);
const clearPlaceholder = useCallback((target, callback) => {
const placeholder = target.textContent;
target.classList.add('disappear');
if (placeholder.length > 0) {
setTimeout(function () {
target.textContent = '';
clearPlaceholder(target, callback);
}, 1000);
return true;
}
callback();
}, []);
const loopThroughSuggestions = useCallback(
(target, index) => {
if (expand) {
target.textContent = '';
return true;
}
fillPlaceholder(target, index, 0, function () {
setTimeout(function () {
clearPlaceholder(target, function () {
loopThroughSuggestions(target, (index + 1) % suggestions.length);
});
}, 2000);
});
},
[clearPlaceholder, expand, fillPlaceholder]
);
useEffect(() => {
if (!expand) {
const targetInput =
document.getElementsByClassName('search-placeholder')[0];
if (targetInput) {
loopThroughSuggestions(targetInput, 0);
}
}
}, [expand, loopThroughSuggestions]);
const trail = useMemo(() => {
const styles = [];
[0, 0, 0].map((element, index) => {
styles.push({
animationDelay: `${index * 250}ms`,
});
return null;
});
return styles;
}, []);
const handleClose = useCallback(() => {
setSearchValue('');
setResults([]);
}, []);
const handleChange = useCallback((event) => {
setSearchValue(event.target.value);
}, []);
useKeyPressEvent('/', () => {
searchInput.current.focus();
});
useKeyPressEvent('Escape', () => {
handleClose();
searchInput.current.blur();
});
return (
<div className="Search">
<label className="fadeInUp" style={trail[0]}>
{t('Search your district or state')}
</label>
<div className="line fadeInUp" style={trail[1]}></div>
<div className="search-input-wrapper fadeInUp" style={trail[2]}>
<input
type="text"
value={searchValue}
ref={searchInput}
onFocus={setExpand.bind(this, true)}
onBlur={setExpand.bind(this, false)}
onChange={handleChange}
/>
{!expand && searchValue === '' && (
<span className="search-placeholder"></span>
)}
<div className={`search-button`}>
<Icon.Search />
</div>
{searchValue.length > 0 && (
<div className={`close-button`} onClick={handleClose}>
<Icon.X />
</div>
)}
</div>
{results.length > 0 && (
<div className="results">
{results.map((result, index) => (
<Link key={index} to={`state/${result.route}`}>
<div className="result">
<div className="result-left">
<div className="result-name">
{`${result.name}`}
{result.type === 'district' &&
`, ${STATE_NAMES[result.route]}`}
</div>
</div>
<div className="result-type">
<span>{[result.route]}</span>
<Icon.ArrowRightCircle size={14} />
</div>
</div>
</Link>
))}
</div>
)}
{expand && (
<>
<div className="expanded">
<div className="expanded-left">
<h3>{t('District')}</h3>
<div className="suggestions">
{districtSuggestions.map((suggestion, index) => (
<div className="suggestion" key={index}>
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, suggestion);
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t(suggestion)}
</h4>
</div>
))}
</div>
</div>
<div className="expanded-right">
<h3>{t('State/UT')}</h3>
<div className="suggestions">
{stateSuggestions.map((suggestion, index) => (
<div className="suggestion" key={index}>
<div>-</div>
<h4
onMouseDown={(event) => {
event.preventDefault();
setNativeValue(searchInput.current, suggestion);
searchInput.current.dispatchEvent(
new Event('input', {bubbles: true})
);
}}
>
{t(suggestion)}
</h4>
</div>
))}
</div>
</div>
</div>
</>
)}
</div>
);
}
Example #5
Source File: index.jsx From erp-crm with MIT License | 4 votes |
export default function AutoCompleteAsync({ entity, displayLabels, searchFields, outputValue = '_id', value, /// this is for update onChange, /// this is for update }) { const [selectOptions, setOptions] = useState([]); const [currentValue, setCurrentValue] = useState(undefined); const isUpdating = useRef(true); const isSearching = useRef(false); const [searching, setSearching] = useState(false); const [valToSearch, setValToSearch] = useState(''); const [debouncedValue, setDebouncedValue] = useState(''); const [, cancel] = useDebounce( () => { // setState("Typing stopped"); setDebouncedValue(valToSearch); }, 500, [valToSearch] ); const asyncSearch = (options) => { return request.search({ entity, options }); }; let { onFetch, result, isSuccess, isLoading } = useOnFetch(); const labels = (optionField) => { return displayLabels.map((x) => optionField[x]).join(' '); }; useEffect(() => { if (debouncedValue != '') { const options = { q: debouncedValue, fields: searchFields, }; onFetch(() => asyncSearch(options)); } return () => { cancel(); }; }, [debouncedValue]); const onSearch = (searchText) => { if (searchText && searchText != '') { isSearching.current = true; setSearching(true); setOptions([]); setCurrentValue(undefined); setValToSearch(searchText); } }; useEffect(() => { if (isSearching.current) { if (isSuccess) { setOptions(result); } else { setSearching(false); setCurrentValue(undefined); setOptions([]); } } }, [isSuccess, result]); useEffect(() => { // this for update Form , it's for setField if (value && isUpdating.current) { if (!isSearching.current) { setOptions([value]); } setCurrentValue(value[outputValue] || value); // set nested value or value onChange(value[outputValue] || value); isUpdating.current = false; } }, [value]); return ( <Select loading={isLoading} showSearch allowClear placeholder={'Search Here'} defaultActiveFirstOption={false} showArrow={false} filterOption={false} notFoundContent={searching ? '... Searching' : 'Not Found'} value={currentValue} onSearch={onSearch} onChange={(newValue) => { if (onChange) { onChange(newValue[outputValue] || newValue); } }} > {selectOptions.map((optionField) => ( <Select.Option key={optionField[outputValue] || optionField} value={optionField[outputValue] || optionField} > {labels(optionField)} </Select.Option> ))} </Select> ); }
Example #6
Source File: index.jsx From erp-crm with MIT License | 4 votes |
function SearchItemComponent({ config, onRerender }) {
let { entity, searchConfig } = config;
const { displayLabels, searchFields, outputValue = '_id' } = searchConfig;
const dispatch = useDispatch();
const { crudContextAction } = useCrudContext();
const { panel, collapsedBox, readBox } = crudContextAction;
const { result, isLoading, isSuccess } = useSelector(selectSearchedItems);
const [selectOptions, setOptions] = useState([]);
const [currentValue, setCurrentValue] = useState(undefined);
const isSearching = useRef(false);
const [searching, setSearching] = useState(false);
const [valToSearch, setValToSearch] = useState('');
const [debouncedValue, setDebouncedValue] = useState('');
const [, cancel] = useDebounce(
() => {
setDebouncedValue(valToSearch);
},
500,
[valToSearch]
);
const labels = (optionField) => {
return displayLabels.map((x) => optionField[x]).join(' ');
};
useEffect(() => {
if (debouncedValue != '') {
const options = {
q: debouncedValue,
fields: searchFields,
};
dispatch(crud.search({ entity, options }));
}
return () => {
cancel();
};
}, [debouncedValue]);
const onSearch = (searchText) => {
if (searchText && searchText != '') {
isSearching.current = true;
setSearching(true);
setOptions([]);
setCurrentValue(undefined);
setValToSearch(searchText);
}
};
const onSelect = (data) => {
const currentItem = result.find((item) => {
return item[outputValue] === data;
});
dispatch(crud.currentItem({ data: currentItem }));
panel.open();
collapsedBox.open();
readBox.open();
onRerender();
};
useEffect(() => {
if (isSearching.current) {
if (isSuccess) {
setOptions(result);
} else {
setSearching(false);
setCurrentValue(undefined);
setOptions([]);
}
}
}, [isSuccess, result]);
return (
<Select
loading={isLoading}
showSearch
allowClear
placeholder={<SearchOutlined style={{ float: 'right', padding: '8px 0' }} />}
defaultActiveFirstOption={false}
showArrow={false}
filterOption={false}
notFoundContent={searching ? '... Searching' : <Empty />}
value={currentValue}
onSearch={onSearch}
style={{ width: '100%' }}
onSelect={onSelect}
>
{selectOptions.map((optionField) => (
<Select.Option key={optionField[outputValue]} value={optionField[outputValue]}>
{labels(optionField)}
</Select.Option>
))}
</Select>
);
}