My main objective is to indent the space within the text area by a particular amount once I click the Tab button.
I am using React JS and Bootstrap. I have created a bootstrap text area in the render function like so.
<textarea class="col-12 form-control-lg" id="exampleFormControlTextarea1"placeholder="Write some Lyrics" rows="50" onKeyDown={this.useTab()} value={this.state.lyrics}
onChange={e => this.setState({ lyrics : e.target.value },()=>{
this.updateSongs("Body")
})}
</textarea>
Outside my render function I am running the useTab() method.
useTab(e) {
console.log(e.keyCode); //press TAB and get the keyCode
}
I get the below error on running this code.
Unhandled Rejection (TypeError): Cannot read property 'keyCode' of undefined
I did refer to the below solution but was still unable to fix the error.
ReactJS handle tab character in textarea
Do I have to bind the function in the constructor? I'm not really sure why the event is not being captured and what I seem to be missing here.
Please follow this example:
class App extends React.Component { constructor() { super(); this.textAreaRef = React.createRef(); this.state = { lyrics: "" }; } onChange = event => { this.setState({ lyrics: event.target.value }); }; // Using arrow function so no need to bind 'this' onKeyDown = event => { // 'event.key' will return the key as a string: 'Tab' // 'event.keyCode' will return the key code as a number: Tab = '9' // You can use either of them if (event.keyCode === 9) { // Prevent the default action to not lose focus when tab event.preventDefault(); // Get the cursor position const { selectionStart, selectionEnd } = event.target; // update the state this.setState( prevState => ({ lyrics: prevState.lyrics.substring(0, selectionStart) + "\t" + // '\t' = tab, size can be change by CSS prevState.lyrics.substring(selectionEnd) }), // update the cursor position after the state is updated () => { this.textAreaRef.current.selectionStart = this.textAreaRef.current.selectionEnd = selectionStart + 1; } ); } }; render() { return ( <div className="App"> <textarea ref={this.textAreaRef} className="col-12 form-control-lg" placeholder="Write some Lyrics" rows="50" value={this.state.lyrics} onChange={this.onChange} onKeyDown={this.onKeyDown} /> </div> ); } } ReactDOM.render( <App />, document.getElementById('root'))
.App { padding: 0.5rem; } /* control tab size */ textarea { tab-size: 8; }
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="root"></div>
You need to add an event listener for your useTab
function:
document.addEventListener('keydown', useTab);
Edit:
Instead of an event listener, you can use the onKeyDown
handler in your input
useTab = (event) => {
event.preventDefault();
console.log(event.key)
}
render: function(){
return(
<div>
<input onKeyDown={this.useTab} />
</div>
);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.