How do I detect "shift+enter" and generate a new line in Textarea?
JavascriptJqueryHtmlCssJavascript Problem Overview
Currently, if the person presses enter inside the text area, the form will submit.
Good, I want that.
But when they type shift + enter, I want the textarea to move to the next line: \n
How can I do that in JQuery
or plain JavaScript as simple as possible?
Javascript Solutions
Solution 1 - Javascript
Easy & Elegant solution:
First, pressing Enter inside a textarea does not submit the form unless you have script to make it do that. That's the behaviour the user expects and I'd recommend against changing it. However, if you must do this, the easiest approach would be to find the script that is making Enter submit the form and change it. The code will have something like
if (evt.keyCode == 13) {
form.submit();
}
... and you could just change it to
if (evt.keyCode == 13 && !evt.shiftKey) {
form.submit();
}
On the other hand, if you don't have access to this code for some reason, you need to do the following to make it work in all major browsers even if the caret is not at the end of the text:
jsFiddle: http://jsfiddle.net/zd3gA/1/
Code:
function pasteIntoInput(el, text) {
el.focus();
if (typeof el.selectionStart == "number"
&& typeof el.selectionEnd == "number") {
var val = el.value;
var selStart = el.selectionStart;
el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
el.selectionEnd = el.selectionStart = selStart + text.length;
} else if (typeof document.selection != "undefined") {
var textRange = document.selection.createRange();
textRange.text = text;
textRange.collapse(false);
textRange.select();
}
}
function handleEnter(evt) {
if (evt.keyCode == 13 && evt.shiftKey) {
if (evt.type == "keypress") {
pasteIntoInput(this, "\n");
}
evt.preventDefault();
}
}
// Handle both keydown and keypress for Opera, which only allows default
// key action to be suppressed in keypress
$("#your_textarea_id").keydown(handleEnter).keypress(handleEnter);
Solution 2 - Javascript
Better use simpler solution:
Tim's solution below is better I suggest using that: https://stackoverflow.com/a/6015906/4031815
My solution
I think you can do something like this..
EDIT : Changed the code to work irrespective of the caret postion
First part of the code is to get the caret position.
Ref: https://stackoverflow.com/questions/263743/how-to-get-cursor-position-in-textarea
function getCaret(el) {
if (el.selectionStart) {
return el.selectionStart;
} else if (document.selection) {
el.focus();
var r = document.selection.createRange();
if (r == null) {
return 0;
}
var re = el.createTextRange(), rc = re.duplicate();
re.moveToBookmark(r.getBookmark());
rc.setEndPoint('EndToStart', re);
return rc.text.length;
}
return 0;
}
And then replacing the textarea value accordingly when Shift + Enter together , submit the form if Enter is pressed alone.
$('textarea').keyup(function (event) {
if (event.keyCode == 13) {
var content = this.value;
var caret = getCaret(this);
if(event.shiftKey){
this.value = content.substring(0, caret - 1) + "\n" + content.substring(caret, content.length);
event.stopPropagation();
} else {
this.value = content.substring(0, caret - 1) + content.substring(caret, content.length);
$('form').submit();
}
}
});
Here is a demo
Solution 3 - Javascript
Most of these answers overcomplicate this. Why not try it this way?
$("textarea").keypress(function(event) {
if (event.keyCode == 13 && !event.shiftKey) {
submitForm(); //Submit your form here
return false;
}
});
No messing around with caret position or shoving line breaks into JS. Basically, the function will not run if the shift key is being pressed, therefore allowing the enter/return key to perform its normal function.
Solution 4 - Javascript
Why not just
$(".commentArea").keypress(function(e) {
var textVal = $(this).val();
if(e.which == 13 && e.shiftKey) {
}
else if (e.which == 13) {
e.preventDefault(); //Stops enter from creating a new line
this.form.submit(); //or ajax submit
}
});
Solution 5 - Javascript
Here is an AngularJS solution using ng-keyup if anyone has the same issue using AngularJS.
ng-keyup="$event.keyCode == 13 && !$event.shiftKey && myFunc()"
Solution 6 - Javascript
Use the jQuery hotkeys plugin and this code
jQuery(document).bind('keydown', 'shift+enter',
function (evt){
$('textarea').val($('#textarea').val() + "\n");// use the right id here
return true;
}
);
Solution 7 - Javascript
Using ReactJS ES6 here's the simplest way
shift + enter New Line at any position
enter Blocked
class App extends React.Component {
constructor(){
super();
this.state = {
message: 'Enter is blocked'
}
}
onKeyPress = (e) => {
if (e.keyCode === 13 && e.shiftKey) {
e.preventDefault();
let start = e.target.selectionStart,
end = e.target.selectionEnd;
this.setState(prevState => ({ message:
prevState.message.substring(0, start)
+ '\n' +
prevState.message.substring(end)
}),()=>{
this.input.selectionStart = this.input.selectionEnd = start + 1;
})
}else if (e.keyCode === 13) { // block enter
e.preventDefault();
}
};
render(){
return(
<div>
New line with shift enter at any position<br />
<textarea
value={this.state.message}
ref={(input)=> this.input = input}
onChange={(e)=>this.setState({ message: e.target.value })}
onKeyDown={this.onKeyPress}/>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='root'></div>
Solution 8 - Javascript
I found this thread looking for a way to control Shift + any key. I pasted together other solutions to make this combined function to accomplish what I needed. I hope it helps someone else.
function () {
return this.each(function () {
$(this).keydown(function (e) {
var key = e.charCode || e.keyCode || 0;
// Shift + anything is not desired
if (e.shiftKey) {
return false;
}
// allow backspace, tab, delete, enter, arrows, numbers
//and keypad numbers ONLY
// home, end, period, and numpad decimal
return (
key == 8 ||
key == 9 ||
key == 13 ||
key == 46 ||
key == 110 ||
key == 190 ||
(key >= 35 && key <= 40) ||
(key >= 48 && key <= 57) ||
(key >= 96 && key <= 105));
});
});
Solution 9 - Javascript
I use div by adding contenteditable true instead of using textarea.
Hope can help you.
$("#your_textarea").on('keydown', function(e){//textarea keydown events
if(e.key == "Enter")
{
if(e.shiftKey)//jump new line
{
// do nothing
}
else // do sth,like send message or else
{
e.preventDefault();//cancell the deafult events
}
}
})
Solution 10 - Javascript
Another Solution for detecting Shift+Enter Key with Angular2+
Inside Component.html
<input type="text" (keydown.shift.enter)="newLine($event)">
Inside Component.ts
newLine(event){
if(event.keyCode==13 && event.shiftKey){
alert('Shift+Enter key Pressed');
}
}
Solution 11 - Javascript
In case someone is still wondering how to do this without jQuery.
HTML
<textarea id="description"></textarea>
Javascript
const textarea = document.getElementById('description');
textarea.addEventListener('keypress', (e) => {
e.keyCode === 13 && !e.shiftKey && e.preventDefault();
})
Vanilla JS
var textarea = document.getElementById('description');
textarea.addEventListener('keypress', function(e) {
if(e.keyCode === 13 && !e.shiftKey) {
e.preventDefault();
}
})
Solution 12 - Javascript
This works for me!
$("#your_textarea").on('keydown', function(e){
if(e.keyCode === 13 && !e.shiftKey)
{
$('form').submit();
}
});
Solution 13 - Javascript
And jquery example
$.fn.pressEnter = function(fn) {
return this.each(function() {
$(this).bind('enterPress', fn);
$(this).keyup(function(e){
/*When SHIFT return false*/
if(e.shiftKey==true) return false;
if(e.keyCode == 13)
{
/*You can do the thing on ENTER*/
alert('Enter press');
}
})
});
};
$('.exampleClass').pressEnter(function(){})
div{
width:200px;
height:100px;
border:solid 1px #000;
float:left;
}
textarea{
width:200px;
height:100px;
border:solid 1px #000;
float:right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="exampleClass" contenteditable></div>
<textarea class="exampleClass"></textarea>
Solution 14 - Javascript
using ng-keyup
directive in angularJS, only send a message on pressing Enter
key and Shift+Enter
will just take a new line.
ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"
Solution 15 - Javascript
This code works perfectly fine for my purpose
document.getElementById('text').addEventListener('keypress', (e) => {
if (e.key == 'Enter' && !e.shiftKey) {
e.preventDefault()
console.log('your code goes here');
}
if (e.key == 'Enter' && e.shiftKey) {
e.preventDefault();
console.log("insertLineBreak");
const txtArea = document.getElementById('text');
txtArea.value += '\r\n';
}
})
Solution 16 - Javascript
I know this is an old question, but I wanted to toss in an implicit observation that some might want to consider if using Shift
+ A-Z
.
document.onkeydown = (k) => {
if (k.key === "Q") {
console.log("Shift + Q");
}
}
You can check for a key by its case, like "Q"
or "q"
. If doing the former, then it's implied that Shift
is being pressed since it's a capital letter.
One bug here where functionality is concerned is if CapsLock
is on. But if, like me, you're utilizing it in a personal script, then it's not really a big deal.
Another potential benefit might be "hiding" an explicit condition looking for the Shift
key to be pressed. This is admittedly a half-baked suggestion, though.
Solution 17 - Javascript
Some complicated solutions sending \n
are not necessary.
On keydown
event just return the key 13
if shift is pressed
$("#mytestarea").keydown(function (e) {
if (e.keyCode == 13) { // Enter pressed
//No shift or alt or ctrl
if (!e.shiftKey && !e.altKey && !e.ctrlKey) {
SendMsg(); // or submit or what you wan't
}
if (e.shiftKey) {
//replace the shift for keycode 13 only
return 13;
}
//method to prevent from default behaviour
e.preventDefault();
}
});
Solution 18 - Javascript
<input type="text" onkeydown="handleMessageKeydown" />
or some content editable element:
<div contenteditable="true" onchange="handleMessageKeydown" />
handleMessageKeydown(e) {
if (!e.shiftKey && e.key === "Enter") {
e.preventDefault()
sendMessage()
}
}
if shift is pressed with enter then it will create new lines otherwise it will fall inside the if condition given above. Inside the if condition, the e.preventDefault() line is the most important. For a keydown event handler, the e.preventDefault() stops running the operation so that u can perform your own operations like sending messages to server etc.
Solution 19 - Javascript
Here is the best way to do
if (e.key === 'Enter') {
console.log('enter');
}
if (e.key === 'Enter' && e.ctrlKey) {
console.log('clt+enter');
}
if (e.key === 'Enter' && e.ctrlKey && e.shiftKey) {
console.log('clt+shift+enter');
}