18

I've written a bit of code in my keyboard event handler to insert a <br> in response to the press of the Enter key:

event.preventDefault();
document.execCommand('InsertHTML', true, '<br>');

This only works if the cursor is between two Letters, if its on the end i need two <br>-Elements. Can i detect if i'm on the end of a Line? Or some other working idea for the Enter problem?

I also tried to catch the normal key-event (wothout the ctrl-Key pressed) and create a keyboard-event with JS where the Enter Key is pressed together with the ctrl. But this dosn't work…

It only has to Work in Webkit/Safari…

Shog9
  • 156,901
  • 35
  • 231
  • 235
Phil
  • 327
  • 1
  • 4
  • 12

2 Answers2

28

In order to solve your problem, always keep a br element as the last element of your contenteditable div. This will ensure predictable behavior when injecting a br element vs. the browser default of injecting div elements. You can check the lastChild on keyup and mouseup to make sure it's a br element. Assuming you have a document like:

<div id="editable" contenteditable="true"></div>

You can use the following JavaScript (w/ jQuery 1.4+) to keep a br element as the last element and inject a br element instead of div div:

$(function(){

  $("#editable")

    // make sure br is always the lastChild of contenteditable
    .live("keyup mouseup", function(){
      if (!this.lastChild || this.lastChild.nodeName.toLowerCase() != "br") {
        this.appendChild(document.createChild("br"));
      }
    })

    // use br instead of div div
    .live("keypress", function(e){
      if (e.which == 13) {
        if (window.getSelection) {
          var selection = window.getSelection(),
              range = selection.getRangeAt(0),
              br = document.createElement("br");
          range.deleteContents();
          range.insertNode(br);
          range.setStartAfter(br);
          range.setEndAfter(br);
          range.collapse(false);
          selection.removeAllRanges();
          selection.addRange(range);
          return false;
        }
      }
    });

});

Tested on Apple OS X w/ Google Chrome 7, Mozilla Firefox 3.6, Apple Safari 5). Try using ierange to get this to work in Windows Internet Explorer.

Jake McGraw
  • 55,558
  • 10
  • 50
  • 63
  • 5
    No need for `range.collapse(false);`: you've already positioned the start and the end of the range. An alternative to IERange is my own Rangy (http://code.google.com/p/rangy), which is similar in concept but more fully realized (and actively maintained). – Tim Down May 18 '11 at 09:09
0

I would bind a function to the keyup event to delete and change to
using regEx. So even if it creates strange markup, it will be fixed.

Using jQuery:

$('.myEditable').keyup(function(){
   var sanitazed = $(this).text().replace(/<div[^<]*?>/g, '').replace(/<\/div[^<]*?>/g, '<br>');
   $(this).text(sanitazed);
});
Bakaburg
  • 3,165
  • 4
  • 32
  • 64
  • 4
    1) .html() must be used instead of .text() 2) it works, but cursor remains before
    , not after it (after pressing Enter).
    – Meglio Mar 21 '13 at 20:00