0

Let me outline the question more clearly, since it seems misunderstood in the comments.

To the core of it, what I want is to replace a specific character a with the input ab in the moment it is being typed. I cannot do a replace-all command, since that hits more a's than just the typed one.

The method I have shown below does remove the a and add ab instead, but not at the same location. The ab is added at the end of the input, not at the place where the a was typed. So it does not do replacement as wanted.

THE ACTUAL SITUATION:

When the enter button is pressed I want the resulting \n changed into <br>\n.

From much searching I have come to something like this (the enter key has keycode 13):

jQuery('textarea#comment').keyup(function(e){
    var content = jQuery(this).val();
    if(e.keyCode == '13') {
        e.preventDefault(); 
        content=content+"<br />\n";
        jQuery('textarea#comment').val(content);
    }

});

But this code piece does not replace the typed \n character with <br>\n. It merely prevents the typed character from being printed and then appends <br>\n at the end of the content. This will not work when the user moves his cursor and starts writing somewhere else than at the end. The <br>\n is simply being added at a wrong location.

The line content=content+"<br />\n"; is clearly incorrect to use. I need to know where the typed character is located so that I can replace it at that location or I need to edit the typed character on the fly before it is being printed on the screen.

Many other answers to similar questions give a replace-all solution. This will not work for me since the search term \n is included in the paste term <br>\n.

Steeven
  • 4,057
  • 8
  • 38
  • 68
  • https://stackoverflow.com/questions/784539/how-do-i-replace-all-line-breaks-in-a-string-with-br-tags – Dimash Aug 11 '17 at 12:57
  • @Dimash The solution there is what I cannot do (see my last sentence) – Steeven Aug 11 '17 at 12:58
  • You want to add only `
    ` to the end of the sentence, so why append `
    \n` ?
    – Hamza Abdaoui Aug 11 '17 at 13:00
  • You could do this by: store the caret (cursor position), change the text, restore the cursor position. https://stackoverflow.com/questions/263743/how-to-get-the-caret-position-in-a-textarea-in-characters-from-the-start – freedomn-m Aug 11 '17 at 13:00
  • The problem is that you're trying to add a `
    ` tag to a `textarea` that obviously doesn't pass HTML. You need to use `\n` and not `
    ` if you're showing it in a text field. There's also no reason to reset the content of the textarea if you haven't actually added anything (which you haven't.. you only touch `content` if the keyCode is 13)
    – h2ooooooo Aug 11 '17 at 13:00
  • *"When the enter button is pressed I want the resulting \n changed into
    \n."* - do you? Are you sure this isn't an XY problem? What are you actually trying to solve?
    – freedomn-m Aug 11 '17 at 13:01
  • *"It merely prevents the typed character from being printed"* - put `jQuery('textarea#comment').val(content);` inside the `if [13]` – freedomn-m Aug 11 '17 at 13:03
  • @HamzaAbdaoui I need the `
    ` added to have it saved in a database. I do though still want the line break `\n` to be shown during typing, so the text lines are still visually separated.
    – Steeven Aug 11 '17 at 13:10
  • @h2ooooooo and @freedomn-m, thanks for pointing out that the content reset should be inside the `if`. In my simplified example here, I missed that one. – Steeven Aug 11 '17 at 13:13
  • @freedomn-m Thank you for the link, I will look into it. As explained, I am trying to replace a typed character with something else. This is a mere character replacement and not a xy-problem. My issue in this case is that I can't do a replace-all, because the character to replace is included in the content to be pasted. Please see the edit to the question – Steeven Aug 11 '17 at 13:16
  • If user types `a`, also add `b`. What's the problem here? –  Aug 11 '17 at 13:35
  • @jaymee The problem is that I am not skilled enough to do what you are suggesting... Would you mind expanding on your hint? – Steeven Aug 11 '17 at 14:22

1 Answers1

1

The (unfortunately) tricky part of this is inserting the text at the cursor position rather than at the end of the textarea.

Several past SO questions have addressed how to do this, with varying degrees of browser support; here's a version I lightly modified from this answer to be a jQuery extension rather than a standalone function.

(I'll admit I haven't tested the IE portion of this; my windows box is allll the way upstairs.)

jQuery('textarea#comment').keydown(function(e) {
  if (e.key === 'Enter') { // keyCode is legacy: see https://www.w3.org/TR/DOM-Level-3-Events/#interface-keyboardevent
    $('textarea#comment').insertAtCaret("<br>\n"); // br won't work in a textarea, but I'll assume you have a good reason for this
    e.preventDefault(); // prevent the default character from being added (it can wind up in the wrong place)
  }
});

jQuery.fn.extend({
  insertAtCaret: function(insert) {
    var el = this[0]; // get DOM element instead of jQuery object
    if (document.selection) {
      // IE
      sel = document.selection.createRange();
      sel.text = insert;
    } else if (el.selectionStart || el.selectionStart == '0') {
      // other browsers
      var startPos = el.selectionStart;
      var endPos = el.selectionEnd;
      el.value = el.value.substring(0, startPos) + insert + el.value.substring(endPos, el.value.length);
      el.setSelectionRange(endPos + insert.length, endPos + insert.length); // put the cursor at the end of the inserted text
    } else {
      // last resort, shouldn't ever get here
      this[0].value += insert;
    }
  }
})
textarea {
  width: 100%;  height: 5em
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="comment"></textarea>

Alternative approaches (that don't work)

  • You might think you could just trigger additional keydown events, like this. This doesn't actually insert the character, though; it just fires the event. (It will also set off an infinite loop of keydown events if you fire it during a keydown watcher...)
  • You might also think you could create and dispatch your own keyboard events like this. Reportedly that can be made to work, in some browsers, if the wind is blowing in the right direction, but I certainly wasn't able to.
Daniel Beck
  • 20,653
  • 5
  • 38
  • 53