How do I detect "shift+enter" and generate a new line in Textarea?

JavascriptJqueryHtmlCss

Javascript 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');
  }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTIMEXView Question on Stackoverflow
Solution 1 - JavascriptTim DownView Answer on Stackoverflow
Solution 2 - JavascriptJishnu A PView Answer on Stackoverflow
Solution 3 - JavascriptMatthew GoodwinView Answer on Stackoverflow
Solution 4 - JavascriptLiam HallView Answer on Stackoverflow
Solution 5 - JavascriptTomberyView Answer on Stackoverflow
Solution 6 - JavascriptThariamaView Answer on Stackoverflow
Solution 7 - JavascriptLiamView Answer on Stackoverflow
Solution 8 - JavascriptSpencer SullivanView Answer on Stackoverflow
Solution 9 - JavascriptHsinhsin HungView Answer on Stackoverflow
Solution 10 - JavascriptVishal DhawanView Answer on Stackoverflow
Solution 11 - JavascriptJaco AhmadView Answer on Stackoverflow
Solution 12 - JavascriptMȍhǟmmǟd ȘamȋmView Answer on Stackoverflow
Solution 13 - JavascriptTsolovView Answer on Stackoverflow
Solution 14 - JavascriptAbdallah OkashaView Answer on Stackoverflow
Solution 15 - JavascriptElliot404View Answer on Stackoverflow
Solution 16 - JavascriptdsasmblrView Answer on Stackoverflow
Solution 17 - JavascriptRui CaramalhoView Answer on Stackoverflow
Solution 18 - JavascriptBaraja SwargiaryView Answer on Stackoverflow
Solution 19 - Javascriptkumbhani bhaveshView Answer on Stackoverflow