Reputation: 41
I am using React Select. I realized that with an input value it only returns the items that have that value included in their string (order does not matter). I would like to change it so that those that match the input string more closely are sorted at the top ex: if I type Veteran it shouldn't return Organization of veterans, Veterans community. It should return the second one first. I am not the best with javascript so please explain as much as you can.
const AutoComplete = (props) => {
const filterOrgs = async (inputValue) => {
let array = []
await getOrgs(inputValue)
.then(res=>{
setLocalStorage(res)
return res.map(i=>array.push({label:i.site_name}))
})
return getValues(array, inputValue)
};
const promiseOptions = inputValue =>
new Promise(resolve => {
inputValue = inputValue.charAt(0).toUpperCase()
setTimeout(() => {
resolve(filterOrgs(inputValue));
}, 1000);
});
const setLocalStorage=(data)=>{
return localStorage.setItem(1, JSON.stringify(data))
}
const getValues=(array,inputValue)=>{
return array.slice(0,10).filter(i =>
i.label.toLowerCase().includes(inputValue.toLowerCase())
)
}
return (
<AsyncSelect cacheOptions defaultOptions loadOptions={promiseOptions} className='asyncSelect' id='asyncType' name={props.name} onChange={props.handleChange}/>
);
}
export default AutoComplete;
Upvotes: 1
Views: 1656
Reputation: 462
Currently, your filter in getValues uses the .includes(...)
and .slice(0,10)
methods to filter organizations. This will return an array of the top 10 filtered organizations matching your criteria.
If you want to have your array sorted differently, then you should use the sort
method and implement your custom sort behavior here.
So, your new get values will look like this:
const getValues=(array,inputValue)=>{
return array.slice(0,10).filter(i =>
i.label.toLowerCase().includes(inputValue.toLowerCase())
.sort((org1, org2) => {
// can't remember the real syntax here if we need a return or not...
// you may also need to swap the directions of the subtraction here.
// the key is to use indexOf to find the index where the substring is located in your match and compare in a custom sort.
org1.indexOf(inputValue.toLowerCase()) - org2.indexOf(inputValue.toLowerCase());
})
)
}
Again, so you can see how this array is being manipulated almost in a beautiful order. First slice, then filter the slice, then sort the sliced and filtered array.
const getValues = (array, inputValue) => {
return array
.slice(0, 10)
.filter((i) => i.label.toLowerCase().includes(inputValue.toLowerCase()))
.sort(...);
};
Links for your reference:
Upvotes: 1