React-autosuggest: Capture more events from keyboard

Created on 3 Jun 2016  路  10Comments  路  Source: moroshko/react-autosuggest

fantastic plugin, thanks for the work.
I would like to capture the "ENTER" event (return key) and when user is typing "SPACE" character.
I tried to add the onKeyPress property in the Autosuggest component but this prop does not get propagated to the input field.

I also would like to have an event generated when the user is leaving the input field.

Most helpful comment

Came across this issue while trying to capture the 'enter' key press.

I solved it by attaching an onKeyDown prop to inputProps

https://github.com/moroshko/react-autosuggest/blob/master/src/Autosuggest.js#L274

i.e.

onKeyDown(e) {
    if (e.keyCode === 13) { // Enter
        // Stop it here
        e.preventDefault();
        e.stopPropagation();
        // Do something else...
    }
}

render() {
    const {value, suggestions, focusInputOnSuggestionClick} = this.state;
    const inputProps = {
        placeholder: 'Find something...',
        onChange: this.onChange,
        onKeyDown: this.onKeyDown // CAPTURE KEY PRESSES
    };

    <Autosuggest
        inputProps={inputProps}
        suggestions={suggestions}
        onSuggestionsUpdateRequested={this.onSuggestionsUpdateRequested}
        getSuggestionValue={this.getSuggestionValue}
        renderSuggestion={this.renderSuggestion}
        onSuggestionSelected={this.onSuggestionSelected}
        focusInputOnSuggestionClick={focusInputOnSuggestionClick}
    />
}

All 10 comments

I'd love to get an answer for this too. In our current application, we'd like the suggestions to display something different if user keys ENTER as opposed to typing.

I tried capturing the onChange events but the component doesn't seem to be detecting ENTER at all.

In my case, I'm just making a one line change to allow onSuggestionsUpdateRequested ({ value, reason }) to receive a new kind of reason. If the user selects a suggestion from the dropdown using ENTER, onSuggestionsUpdateRequested logs a 'enter' reason. If instead a user presses ENTER on the input bar, onSuggestionsUpdateRequeted logs 'enter-input'.

Original code is here: https://github.com/moroshko/react-autosuggest/blob/master/src/Autosuggest.js

case 'Enter':
    {
        var focusedSuggestion = _this2.getFocusedSuggestion();

        closeSuggestions('enter'); // Might need to move this into the if statement depending on your needs

    if (focusedSuggestion !== null) {
        onSuggestionSelected(event, {
             ...
        });
        _this2.maybeCallOnSuggestionsUpdateRequested({ value: value, reason: 'enter' });
    }
    else {
        _this2.maybeCallOnSuggestionsUpdateRequested({ value: value, reason: 'enter-input' }); // Additional line
    }

    break;
}

onSuggestionsUpdateRequested

Came across this issue while trying to capture the 'enter' key press.

I solved it by attaching an onKeyDown prop to inputProps

https://github.com/moroshko/react-autosuggest/blob/master/src/Autosuggest.js#L274

i.e.

onKeyDown(e) {
    if (e.keyCode === 13) { // Enter
        // Stop it here
        e.preventDefault();
        e.stopPropagation();
        // Do something else...
    }
}

render() {
    const {value, suggestions, focusInputOnSuggestionClick} = this.state;
    const inputProps = {
        placeholder: 'Find something...',
        onChange: this.onChange,
        onKeyDown: this.onKeyDown // CAPTURE KEY PRESSES
    };

    <Autosuggest
        inputProps={inputProps}
        suggestions={suggestions}
        onSuggestionsUpdateRequested={this.onSuggestionsUpdateRequested}
        getSuggestionValue={this.getSuggestionValue}
        renderSuggestion={this.renderSuggestion}
        onSuggestionSelected={this.onSuggestionSelected}
        focusInputOnSuggestionClick={focusInputOnSuggestionClick}
    />
}

Thanks @kengoldfarb I needed to do that just now, to prevent the Enter key from reloading the page.

@kengoldfarb do you know if this is expected behavior?

I couldn't find it anywhere in the docs and I am afraid of implementing using an exposed internal feature that will disappear in some odd PR.

Perhaps @moroshko can weigh in here. It's definitely not documented but it does appear to be deliberately exposed:

https://github.com/moroshko/react-autosuggest/blob/master/src/Autosuggest.js#L184

const { value, onBlur, onFocus, onKeyDown } = inputProps;

Thank you @kengoldfarb!

Thank you @kengoldfarb

@kengoldfarb is right, hooking to onKeyDown is the way to go.

I really like @irealva solution, because I really need to differ between an 'enter' event that is made in the searchField and in the dropDownList of suggestions.

I have used @irealva solution in version v9.0.1, I do it like this (I might have missed some things that needs to be done in the code so I do not want to do a pullrequest because the solution is a bit of a hack... So it might just fullfill my needs.

Autosuggest.js

onKeyDown: function onKeyDown(event, data) {
...
case 'enter'
...

                //---------------------------------
                // CODE CHANGE 1 'method'
                //---------------------------------
                const method = highlightedSuggestion !== null ? 'enter' : 'enter-input';

                if (highlightedSuggestion !== null) {
                  var _newValue = getSuggestionValue(highlightedSuggestion);

                  _this2.maybeCallOnChange(event, _newValue, method);

                  _this2.onSuggestionSelected(event, {
                    suggestion: highlightedSuggestion,
                    suggestionValue: _newValue,
                    suggestionIndex: highlightedSuggestionIndex,
                    sectionIndex: highlightedSectionIndex,
                    method: method
                  });

                  _this2.justSelectedSuggestion = true;

                  setTimeout(function () {
                    _this2.justSelectedSuggestion = false;
                  });
                }
                //-----------------------------
                // CODE CHANGE 2 'else'
                //-----------------------------              
                else {
                  _this2.onSuggestionSelected(event, {
                    suggestion: undefined,
                    suggestionValue: undefined,
                    suggestionIndex: undefined,
                    sectionIndex: undefined,
                    method: method
                  });
                }

Using this I can in onSuggestionSelected just switch on 'click' / 'enter' and the new 'enter-input'

Thanx for a great react lib!

Was this page helpful?
0 / 5 - 0 ratings