How to get a selected data item from a Autocomplete component

4 posts, 0 answers
  1. Kyle
    Kyle avatar
    3 posts
    Member since:
    Apr 2019

    Posted 16 Jan 2020 Link to this post

    Hello,

    Is there a way to get the data item from the autocomplete list on a selection event? Right now from my research there is no onSelected event. There is one in the kendo jQuery implementation but nothing for a react implementation. Sure I could use the onChange event but this only fires when the value in the input box changes. There is no way I can identify that the user has selected the value from the list. I can make my own selection event but I would like to avoid this. Please let me know if there is something I am missing concerning this component. I tried using a combo box component as well, still was unable to find the selection event or an easier way to acquire a selected item.

    Below is my current implementation, any assistance would be great. Thanks.

    const mapStateToProps = (state: ApplicationState) => ({
        ...state.accountsStateSlice
    });
    type TypeAheadSearchProps = ReturnType<typeof mapStateToProps>
        & {
            data: Array<any>;
            textField: string;
            apiRequestThunk: (...params: any) => (dispatch: redux.Dispatch<redux.AnyAction>) => Promise<void>;
        }
    type AutoCompleteState = {
        data?: Array<any>;
        value?: string;
        loading?: boolean;
    }

    const TypeAheadSearch = (props: TypeAheadSearchProps) => {
        const [autoComplete, setAutoComplete] = useState<AutoCompleteState>({
            data: props.data,
            value: '',
            loading: false
        });

        const onChange = (event: any) => {
            const value = event.target.value;
            if (value.length > 2) {
                props.apiRequestThunk(value, true);
            }
        }

        useEffect(() => {
            setAutoComplete({
                data: props.accounts,
                loading: false,
            })
        }, [props.accounts])

        return (
            <AutoComplete 
                data={autoComplete.data}
                value={autoComplete.value}
                onChange={onChange}
                loading={autoComplete.loading}
                textField={props.textField}
            />
        )
    }
    export default connect(mapStateToProps, null)(TypeAheadSearch);

     

  2. Kyle
    Kyle avatar
    3 posts
    Member since:
    Apr 2019

    Posted 16 Jan 2020 in reply to Kyle Link to this post

    Thought of a work around in the meantime. Basically just added a onClick event to call a method on the component called onSelection that passes the list item properties to it. Here I can do whatever I need like updating the redux store etc. If there is any other cleaner solution please let me know. Thanks.

    Below is the code with my change.

    const TypeAheadSearch = (props: TypeAheadSearchProps) => {
        const [autoComplete, setAutoComplete] = useState<AutoCompleteState>({
            data: props.data,
            value: '',
            loading: false,
            selectedDataItem: undefined
        });
        const onChange = (event: AutoCompleteChangeEvent) => {
            const value = event.target.value;
            if (value.length > 2) {
                props.apiRequestThunk(value, true);
            }

        }
        const onSelection = (itemProps: ListItemProps) => {
            setAutoComplete({
                selectedDataItem: 
            })
        }
        const itemRender = (li: React.ReactElement<HTMLLIElement>, itemProps: ListItemProps): React.ReactNode => {
            const itemChildren = <span onClick={() => onSelection(itemProps)}>{li.props.children}</span>
            return React.cloneElement(li, li.props, itemChildren);
        }
        useEffect(() => {
            setAutoComplete({
                data: props.accounts,
                loading: false,
            });
        }, [props.accounts])
        return (
            <AutoComplete 
                data={autoComplete.data}
                value={autoComplete.value}
                onChange={onChange}
                loading={autoComplete.loading}
                textField={props.textField}
                itemRender={itemRender}
            />
        )
    }
    export default connect(mapStateToProps, null)(TypeAheadSearch);
  3. Stefan
    Admin
    Stefan avatar
    3008 posts

    Posted 17 Jan 2020 Link to this post

    Hello, Kyle,

    The suggested workaround is a good one as it gives access to the items and can be used if more modifications are needed.

    The faster approach I was able to find is to use the onChange event and only check the type of the event:

    - input - fired when the user types

    - keydown - when the enter key is used to select a value

    - click - when the user selects an item from the list:

    https://stackblitz.com/edit/react-ba27lt?file=app/main.jsx

    Regards,
    Stefan
    Progress Telerik

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  4. Kyle
    Kyle avatar
    3 posts
    Member since:
    Apr 2019

    Posted 17 Jan 2020 in reply to Stefan Link to this post

    Cool. Thanks for the onChange suggestion and the feedback.
Back to Top