How To Take A Key Up/down In Web Chat Using React
I am currently doing bot-framework web chat application using react js.I want to know how can i take a key up/down. As i want to select or highlight through suggestion list using arrow keys. My code which i used for the react component is attached below, PFA,
async handleSuggestionClick(val) {
const newValue = val.currentTarget.textContent;
await this.setState({ typingChecking: "false" },
() => { console.log(this.state.typingChecking) });
await this.setState({ suggestions: [] },
() => { console.log(this.state.suggestions) });
this.state.suggestionCallback.dispatch({
type: 'WEB_CHAT/SET_SEND_BOX',
payload: {
text: newValue,
}
});
await this.setState({ typingChecking: "true" },
() => { console.log(this.state.typingChecking) });
}
<div className="react-container webchat" >
<ReactWebChat directLine={this.state.directLine}
webSocket={true}
store={this.state.storeValue}
sendTypingIndicator={true} />
<div className="SuggestionParent" id="Suggestion1">
{this.state.suggestions.map(suggestion => (
<div className="Suggestion"
onClick={this.handleSuggestionClick}
onKeyDown={this.handleKeyDown}>
{suggestion
.toLowerCase()
.startsWith(this.state.suggestionTypedText) ?
(<div>
<b>
{this.state.suggestionTypedText}
</b>
{suggestion
.toLowerCase()
.replace(this.state.suggestionTypedText, "")}
</div>) :
(<div>{suggestion}</div>
)
}
</div>
))
}
</div>
Answer
From the answer to your duplicate issue: Issues with suggestion list in botframework Webchat React
Keyboard events are generally handled in React using the
onKeyDown
property. I've placed it on an element that contains both Web Chat and your suggestions parent:<div className={ROOT_CSS} onKeyDown={this.handleKeyDown.bind(this)}> <div className={WEB_CHAT_CSS + ''}> <ReactWebChat
That will handle all key presses, so you'll need a way to route to the function for the correct key. You could use a
switch
statement but the source code for [react-autocomplete][3] uses a lookup object and I think that's smart.keyDownHandlers = { ArrowDown(event) { this.moveHighlight(event, 1); }, ArrowUp(event) { this.moveHighlight(event, -1); }, Enter(event) { const {suggestions} = this.state; if (!suggestions.length) { // menu is closed so there is no selection to accept -> do nothing return } event.preventDefault() this.applySuggestion(suggestions[this.state.highlightedIndex]); }, } handleKeyDown(event) { if (this.keyDownHandlers[event.key]) this.keyDownHandlers[event.key].call(this, event) }
I've centralized the functionality for the up and down arrows into one function:
moveHighlight
. You will need to define a new property in your state to keep track of which suggestion has been selected by the keyboard. I'm keeping the namehighlightedIndex
from react-autocomplete.moveHighlight(event, direction) { event.preventDefault(); const { highlightedIndex, suggestions } = this.state; if (!suggestions.length) return; let newIndex = (highlightedIndex + direction + suggestions.length) % suggestions.length; if (newIndex !== highlightedIndex) { this.setState({ highlightedIndex: newIndex, }); } }
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM