Skip to content
Open
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ yarn add react-native-element-dropdown
| data | Array | Yes | Data is a plain array |
| labelField | String | Yes | Extract the label from the data item |
| valueField | String | Yes | Extract the primary key from the data item |
| searchField | String | No | Specify the field of data list you want to search |
| searchField | String | No | Specify the field of data list you want to search |
| searchKeyboardType | KeyboardTypeOptions | No | Specify the field of keyboard type list you want to use |
| onChange | (item: object) => void | Yes | Selection callback |
| onChangeText | (search: string) => void | No | Callback that is called when the text input's text changes |
| onChangeText | (search: string) => void | No | Callback that is called when the text input's text changes |
| value | Item | No | Set default value |
| placeholder | String | No | The string that will be rendered before dropdown has been selected |
| placeholderStyle | TextStyle | No | Styling for text placeholder |
Expand All @@ -62,6 +63,7 @@ yarn add react-native-element-dropdown
| itemTextStyle | TextStyle | No | Styling for text item in list |
| activeColor | String | No | Background color for item selected in list container |
| search | Boolean | No | Show or hide input search |
| searchBothFields | Boolean | No | Search by valueField and labelField |
| searchQuery | (keyword: string, labelValue: string) => Boolean| No | Callback used to filter the list of items |
| inputSearchStyle | ViewStyle | No | Styling for input search |
| searchPlaceholder | String | No | The string that will be rendered before text input has been entered |
Expand Down
49 changes: 43 additions & 6 deletions src/components/Dropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@ import {
View,
ViewStyle,
} from 'react-native';
import { useDetectDevice } from '../../toolkits';
import { useDeviceOrientation } from '../../useDeviceOrientation';
import CInput from '../TextInput';
import { DropdownProps, IDropdownRef } from './model';
import { styles } from './styles';

const { isTablet } = useDetectDevice;
const ic_down = require('../../assets/down.png');

const statusBarHeight: number = StatusBar.currentHeight || 0;
Expand All @@ -61,6 +59,7 @@ const DropdownComponent = React.forwardRef<IDropdownRef, DropdownProps<any>>(
labelField,
valueField,
searchField,
searchKeyboardType,
value,
activeColor = '#F6F7F8',
fontFamily,
Expand All @@ -69,6 +68,7 @@ const DropdownComponent = React.forwardRef<IDropdownRef, DropdownProps<any>>(
searchPlaceholderTextColor = 'gray',
placeholder = 'Select item',
search = false,
searchBothFields = false,
maxHeight = 340,
minHeight = 0,
disable = false,
Expand Down Expand Up @@ -193,9 +193,7 @@ const DropdownComponent = React.forwardRef<IDropdownRef, DropdownProps<any>>(
const _measure = useCallback(() => {
if (ref && ref?.current) {
ref.current.measureInWindow((pageX, pageY, width, height) => {
let isFull = isTablet
? false
: mode === 'modal' || orientation === 'LANDSCAPE';
let isFull = mode === 'modal' || orientation === 'LANDSCAPE';

if (mode === 'auto') {
isFull = false;
Expand Down Expand Up @@ -372,14 +370,38 @@ const DropdownComponent = React.forwardRef<IDropdownRef, DropdownProps<any>>(
return item.indexOf(key) >= 0;
};

const searchBothFieldFunction = (e: any) => {
const item = _get(e, labelField)
?.toLowerCase()
.replace(/\s/g, '')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '');
const key = text
.toLowerCase()
.replace(/\s/g, '')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '');

const item1 = _get(e, valueField)
?.toLowerCase()
.replace(/\s/g, '')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '');

const isLabelMatch = item.indexOf(key) >= 0;
const isValueMatch = item1.indexOf(key) >= 0;

return isLabelMatch || isValueMatch;
};

const propSearchFunction = (e: any) => {
const labelText = _get(e, searchField || labelField);

return searchQuery?.(text, labelText);
};

const dataSearch = data.filter(
searchQuery ? propSearchFunction : defaultFilterFunction
searchQuery ? propSearchFunction : searchBothFields ? searchBothFieldFunction: defaultFilterFunction
);

if (excludeSearchItems.length > 0 || excludeItems.length > 0) {
Expand All @@ -402,6 +424,7 @@ const DropdownComponent = React.forwardRef<IDropdownRef, DropdownProps<any>>(
[
data,
searchQuery,
searchBothFields,
excludeSearchItems,
excludeItems,
searchField,
Expand Down Expand Up @@ -559,6 +582,7 @@ const DropdownComponent = React.forwardRef<IDropdownRef, DropdownProps<any>>(
inputStyle={[inputSearchStyle, font()]}
value={searchText}
autoCorrect={false}
keyboardType={searchKeyboardType || 'default'}
placeholder={searchPlaceholder}
onChangeText={(e) => {
if (onChangeText) {
Expand Down Expand Up @@ -606,6 +630,19 @@ const DropdownComponent = React.forwardRef<IDropdownRef, DropdownProps<any>>(
onContentSizeChange={scrollIndex}
onScrollToIndexFailed={scrollIndex}
data={listData}
ListEmptyComponent={
<View style={styles.item}>
<Text
style={StyleSheet.flatten([
styles.textItem,
itemTextStyle,
font(),
])}
>
No Result Found
</Text>
</View>
}
inverted={isTopPosition ? inverted : false}
renderItem={_renderItem}
keyExtractor={(_item, index) => index.toString()}
Expand Down
3 changes: 3 additions & 0 deletions src/components/Dropdown/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
TextProps,
ImageStyle,
FlatListProps,
KeyboardTypeOptions,
} from 'react-native';

export type IDropdownRef = {
Expand Down Expand Up @@ -42,10 +43,12 @@ export interface DropdownProps<T> {
valueField: keyof T;
searchField?: keyof T;
search?: boolean;
searchBothFields?: boolean;
searchPlaceholder?: string;
searchPlaceholderTextColor?: string;
disable?: boolean;
autoScroll?: boolean;
searchKeyboardType? : KeyboardTypeOptions | 'default';
showsVerticalScrollIndicator?: boolean;
dropdownPosition?: 'auto' | 'top' | 'bottom';
flatListProps?: Omit<FlatListProps<any>, 'renderItem' | 'data'>;
Expand Down