diff --git a/src/CONST.js b/src/CONST.js index 362e53fb0a1a..cc0ebd4f7bab 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1152,6 +1152,7 @@ const CONST = { SPECIAL_CHARS_WITHOUT_NEWLINE: /((?!\n)[()-\s\t])/g, DIGITS_AND_PLUS: /^\+?[0-9]*$/, ALPHABETIC_AND_LATIN_CHARS: /^[a-zA-ZÀ-ÿ ]*$/, + NON_ALPHABETIC_AND_NON_LATIN_CHARS: /[^a-zA-ZÀ-ÿ]/g, POSITIVE_INTEGER: /^\d+$/, PO_BOX: /\b[P|p]?(OST|ost)?\.?\s*[O|o|0]?(ffice|FFICE)?\.?\s*[B|b][O|o|0]?[X|x]?\.?\s+[#]?(\d+)\b/, ANY_VALUE: /^.+$/, diff --git a/src/components/CountryPicker/CountrySelectorModal.js b/src/components/CountryPicker/CountrySelectorModal.js index d16d97741d7c..b917e771e815 100644 --- a/src/components/CountryPicker/CountrySelectorModal.js +++ b/src/components/CountryPicker/CountrySelectorModal.js @@ -6,6 +6,7 @@ import useLocalize from '../../hooks/useLocalize'; import HeaderWithBackButton from '../HeaderWithBackButton'; import SelectionListRadio from '../SelectionListRadio'; import Modal from '../Modal'; +import searchCountryOptions from '../../libs/searchCountryOptions'; const propTypes = { /** Whether the modal is visible */ @@ -33,15 +34,6 @@ const defaultProps = { onCountrySelected: () => {}, }; -function filterOptions(searchValue, data) { - const trimmedSearchValue = searchValue.trim(); - if (trimmedSearchValue.length === 0) { - return []; - } - - return _.filter(data, (country) => country.text.toLowerCase().includes(searchValue.toLowerCase())); -} - function CountrySelectorModal({currentCountry, isVisible, onClose, onCountrySelected, setSearchValue, searchValue}) { const {translate} = useLocalize(); @@ -52,12 +44,13 @@ function CountrySelectorModal({currentCountry, isVisible, onClose, onCountrySele keyForList: countryISO, text: countryName, isSelected: currentCountry === countryISO, + searchValue: `${countryISO}${countryName}`.toLowerCase().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''), })), [translate, currentCountry], ); - const filteredData = filterOptions(searchValue, countries); - const headerMessage = searchValue.trim() && !filteredData.length ? translate('common.noResultsFound') : ''; + const searchResults = searchCountryOptions(searchValue, countries); + const headerMessage = searchValue.trim() && !searchResults.length ? translate('common.noResultsFound') : ''; return ( country.text.toLowerCase().includes(searchValue.toLowerCase())); -} - function StateSelectorModal({currentState, isVisible, onClose, onStateSelected, searchValue, setSearchValue, label}) { const {translate} = useLocalize(); @@ -56,12 +48,13 @@ function StateSelectorModal({currentState, isVisible, onClose, onStateSelected, keyForList: state.stateISO, text: state.stateName, isSelected: currentState === state.stateISO, + searchValue: `${state.stateISO}${state.stateName}`.toLowerCase().replaceAll(CONST.REGEX.NON_ALPHABETIC_AND_NON_LATIN_CHARS, ''), })), [translate, currentState], ); - const filteredData = filterOptions(searchValue, countryStates); - const headerMessage = searchValue.trim() && !filteredData.length ? translate('common.noResultsFound') : ''; + const searchResults = searchCountryOptions(searchValue, countryStates); + const headerMessage = searchValue.trim() && !searchResults.length ? translate('common.noResultsFound') : ''; return ( country.searchValue.includes(trimmedSearchValue)); + + // sort by country code + return _.sortBy(filteredData, (country) => (country.value.toLowerCase() === trimmedSearchValue ? -1 : 1)); +} + +export default searchCountryOptions;