A
Anonymous

User Search with Multi-Select Functionality

<UserSearch adAppRole="" disabled={false} onChange={onUserChange} existDefault={true} user={value?.contact?.displayName} newProp= {} /> export const UserSearch = ({ adAppRole, disabled, onChange, existDefault, user, }) => { const [open, setOpen] = useState(false); const [selected, setSelected] = useState(''); const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null); useEffect(() => { setSelected(user || ''); }, [user]); return ( <Box> <Button variant="outlined" aria haspopup="true" aria expanded={open ? 'true' : undefined} disabled={disabled} onClick={(e) => { setOpen(!open); setAnchorEl(e.currentTarget); }} > {selected === '' ? existDefault ? 'Default' : 'Choose a user from the dropdown' : selected} &nbsp;&nbsp; <i className="fa sharp fa solid fa chevron down" /> </Button> <UserSearchBar show={open} type="knockoutScreen" adAppRoleName={adAppRole} anchor={anchorEl} showConfirmButton={false} onClose={() => setOpen(false)} user={selected} onChange={(user) => { onChange(user.id); setSelected(user.displayName || ''); setOpen(false); }} /> </Box> ); }; export default function UserSearchBar({ type, show, adAppRoleName, anchor, showConfirmButton, user, onClose, onChange, }{ const [pendingValue, setPendingValue] = React.useState<User | undefined>( undefined ); const [text, setText] = useState<string>(user || ''); const [searchFilter, setSearchFilter] = useState<string>(''); const { data: departments } = useGetDepartmentsQuery(); const deptName = React.useMemo(() => { if (departments) { return ( (departments as any).find( (d: Department) => d.adAppRole === adAppRoleName )?.name || '' ); } return ''; }, [departments, adAppRoleName]); const { data } = useSearchUsersQuery( { search: searchFilter, adAppRoleName: adAppRoleName, }, { skip: searchFilter === '' } ); const rows = useMemo(() => { if (data) { return data; } return []; }, [data]); useEffect(() => { const delayDebounceFn = setTimeout(() => { if (text.length >= 3) { setSearchFilter(text); } else { setSearchFilter(''); } }, 500); return () => clearTimeout(delayDebounceFn); }, [text, setSearchFilter]); const handleChange = (user: User | undefined) => { if (user === undefined) return; onChange(user); }; const handleClose = () => { setText(''); setPendingValue(undefined); onClose(); }; return ( <StyledPopper open={show} anchorEl={anchor} placement="bottom start"> <ClickAwayListener onClickAway={handleClose}> <div> <Autocomplete open onClose={( event: React.ChangeEvent<{}>, reason: AutocompleteCloseReason ) => { if (reason === 'escape') { handleClose(); } }} onInputChange={(event, value: string, reason: string) => { if ( value.length > 0 && reason === 'input' && !rows.find((e) => e.displayName === value) ) { setText(value); } }} onChange={(event, newValue, reason) => { setPendingValue(newValue ? newValue : undefined); }} disableCloseOnSelect PopperComponent={PopperComponent} renderTags={() => null} noOptionsText="No Users" renderOption={(props, option, { selected }) => ( <li {...props} style={{ padding: 0 }}> <Box onClick={() => showConfirmButton || showConfirmButton === undefined ? null : handleChange(option) } > {option?.displayName} <br /> <span>{option?.email}</span> </Box> </li> )} options={rows} filterOptions={(options, state) => options} getOptionLabel={(option) => option.displayName || ''} renderInput={(params) => ( <> <Box> <StyledInput size="small" ref={params.InputProps.ref} inputProps={params.inputProps} autoFocus /> </Box> <Divider /> </> )} /> </div> </ClickAwayListener> </StyledPopper> ); } how to make search as multi select and need to have multi selection and also have an option to remove the added users by passing new prop, because we are using same component multiple places

Prompt
Component Preview

About

Learn how to implement multi-select user search in React with Material-UI, including options to add and remove users dynamically across multiple components.

Share

Last updated 1 month ago