web-dev-qa-db-fra.com

Comment détecter "shift + enter" et générer une nouvelle ligne dans Textarea?

Actuellement, si la personne appuie sur enter à l'intérieur de la zone de texte, le formulaire sera soumis.
Bien, je le veux.

Mais quand ils tapent shift + enter, Je veux que la zone de texte passe à la ligne suivante: \n

Comment puis-je le faire avec JQuery ou un code JavaScript aussi simple que possible?

125
TIMEX

Mieux utiliser une solution plus simple:

La solution de Tim ci-dessous est meilleure, je suggère d'utiliser cette méthode: https://stackoverflow.com/a/6015906/4031815


Ma solution

Je pense que tu peux faire quelque chose comme ça ..

EDIT: Modification du code pour qu'il fonctionne quelle que soit la position du caret

La première partie du code consiste à obtenir la position du curseur.

Ref: Comment obtenir la position de la colonne de curseur (pas les pixels) dans une zone de texte, en caractères, depuis le début?

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; 
}

Et puis remplacer la valeur textarea en conséquence lorsque Shift + Enter ensemble, soumettez le formulaire si Enter est pressé seul.

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

Voici une démo

72
Jishnu A P

Solution simple et élégante:

Tout d'abord, en appuyant sur Enter À l'intérieur d'une zone de texte, ne soumettez pas le formulaire, sauf si vous disposez d'un script pour le faire. C'est le comportement attendu par l'utilisateur et je recommande de ne pas le changer. Toutefois, si vous devez le faire, la solution la plus simple consiste à rechercher le script permettant Enter soumettez le formulaire et modifiez-le. Le code aura quelque chose comme

if (evt.keyCode == 13) {
    form.submit();
}

... et vous pouvez simplement le changer en

if (evt.keyCode == 13 && !evt.shiftKey) {
    form.submit();
}

D'autre part, si vous n'avez pas accès à ce code pour une raison quelconque, vous devez procéder comme suit pour le faire fonctionner dans tous les principaux navigateurs, même si le curseur n'est pas à la fin du texte:

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);
133
Tim Down

La plupart de ces réponses compliquent excessivement cela. Pourquoi ne pas l'essayer de cette façon?

$("textarea").keypress(function(event) {
        if (event.keyCode == 13 && !event.shiftKey) {
         submitForm(); //Submit your form here
         return false;
         }
});

Pas de déconner avec la position de curseur ou la ligne de poussée se brise dans JS. Fondamentalement, la fonction ne fonctionnera pas si la touche Maj est enfoncée, permettant ainsi à la touche Entrée/Retour d’exécuter sa fonction normale.

36
Matt Goodwin

Pourquoi pas juste

$(".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
    }
});
16
Liam Hall

Utilisez le jQuery hotkeys plugin et ce code

jQuery(document).bind('keydown', 'shift+enter', 
         function (evt){ 
             $('textarea').val($('#textarea').val() + "\n");// use the right id here
             return true;
         }
);
3
Thariama

Voici une solution AngularJS utilisant ng-keyup si quelqu'un a le même problème avec AngularJS.

ng-keyup="$event.keyCode == 13 && !$event.shiftKey && myFunc()"
3
Tombery

J'ai trouvé ce fil à la recherche d'un moyen de contrôler Shift + n'importe quelle touche. J'ai collé ensemble d'autres solutions pour que cette fonction combinée réalise tout ce dont j'avais besoin. J'espère que ça aide quelqu'un d'autre. 

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));
    });
});
1
Spencer Sullivan

J'utilise div en ajoutant true à contenteditable au lieu d'utiliser textarea.

L'espoir peut vous aider.

$("#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
    }
  }
})
1
Hsinhsin Hung

Au cas où quelqu'un se demanderait toujours comment faire cela sans 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();
    }
})
0
Jaco Ahmad

en utilisant la directive ng-keyup dans angularJS, n'envoyez un message qu'en appuyant sur la touche Enter et Shift+Enter prendra simplement une nouvelle ligne.

ng-keyup="($event.keyCode == 13&&!$event.shiftKey) ? sendMessage() : null"
0
Abdallah Okasha

Pour qui utilise ReactJS ES6, voici le moyen le plus simple

shift + enter Nouvelle ligne

enter Bloqué

class App extends React.Component {

 constructor(){
    super();
    this.state = {
      message: 'Enter is blocked'
    }
  }
  onKeyPress = (e) => {
  
    if (e.keyCode === 13) { // block enter
      e.preventDefault();
    }
    if (e.keyCode === 13 && e.shiftKey) {
      e.preventDefault();
      this.setState(prevState => ({ message: prevState.message+'\n' }))
    }
  };

  render(){
    return(
      <div>
      New line with shift enter<br />
       <textarea 
       value={this.state.message}
       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>
0
Liam