Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force <br> line break in Firefox ContentEditable

I have a JavaScript WYSIWYG editor (not unlike CKEditor) running on a site.

It has a setting that makes IE create <br> line breaks when you press Enter in the editor.

That works great, but unfortunately, Firefox (I've tested with 5 and 7) will still generate <p> elements, and generate <br> s only if you use Shift + Enter.

Is there a way to make Firefox always generate <br> elements in a contentEditable?

like image 905
Pekka Avatar asked Oct 26 '11 10:10

Pekka


People also ask

How do you make a line break in HTML?

To do a line break in HTML, use the <br> tag. Simply place the tag wherever you want to force a line break. Since an HTML line break is an empty element, there's no closing tag.

How do you break a line in HTML without br?

A line break can be added to HTML elements without having to utilize a break return <br> by using pseudo-elements. Pseudo-elements are used to style a specific part of an element. Here we will use ::after to style an HTML element to add a line break.

How do I add a line break in CSS?

A line-break can be added in HTML, using only CSS, by employing the pseudo-class ::after or ::before . In the stylesheet, we use these pseudo-classes, with the HTML class or id, before or after the place where we want to insert a line-break. In myClass::after : Set the content property to "\a" (the new-line character).

How do you use a BR tag?

Definition and UsageThe <br> tag inserts a single line break. The <br> tag is useful for writing addresses or poems. The <br> tag is an empty tag which means that it has no end tag.


2 Answers

From looking at the standards, it looks like this action is the way it is supposed to be handled. Blocks are broken when no modifier is set on an enter key, and <br>'s are used when shift is pressed. [Source].

That said, that does not solve your problem, so let's work on that. This line should do

document.execCommand('insertBrOnReturn', false, true);

Set's it so that when you just hit return, it only puts in a <br> tag. This is only supported by FF, so it shouldn't affect anything on IE. Don't know about other browsers though.

Note: If the user hits Enter a second time, without typing anything, it creates a new paragraph tag no matter what. To prevent this, you can catch the Enter using the keypress event and stop it, or you could insert in a &nbsp; before you continue with the event (what I'd recommend).

The tough part for you with this note is checking on the state of the element on keypress. The lazy solution (and the one I would recommend unless it's important to not do this) is to just insert it before every Enter key. If you want to do it the other way, I would check the .innerHTML for the element and see if the last few characters (without trimming the content) are <br/> (so maybe a regex match on /\<br\s?\/?\>$/).

like image 177
LoveAndCoding Avatar answered Sep 29 '22 11:09

LoveAndCoding


Consider this:

HTML:

<div contentEditable id="input"></div>

CSS:

#input {
    border: 3px solid #07c;
    width: 300px;
    height: 200px;
    white-space: pre;
}

JavaScript:

$( input ).keypress( function ( e ) {
    var sel, node, offset, text, textBefore, textAfter, range;

    sel = window.getSelection();

    // the node that contains the caret
    node = sel.anchorNode;

    // if ENTER was pressed while the caret was inside the input field
    if ( node.parentNode === input && e.keyCode === 13 ) {

        // prevent the browsers from inserting <div>, <p>, or <br> on their own
        e.preventDefault();

        // the caret position inside the node
        offset = sel.anchorOffset;        

        // insert a '\n' character at that position
        text = node.textContent;
        textBefore = text.slice( 0, offset );
        textAfter = text.slice( offset ) || ' ';
        node.textContent = textBefore + '\n' + textAfter;

        // position the caret after that new-line character
        range = document.createRange();
        range.setStart( node, offset + 1 );
        range.setEnd( node, offset + 1 );

        // update the selection
        sel.removeAllRanges();
        sel.addRange( range );
    }
});

Live demo: http://jsfiddle.net/FhEf6/3/

I use '\n' characters instead of BR elements (the DIV has white-space:pre set). As a result, no BR, or P elements are added to the DIV when ENTER is pressed. There is only one TextNode inside the DIV at all times and all new-lines are represented by '\n' characters.

like image 24
Šime Vidas Avatar answered Sep 29 '22 12:09

Šime Vidas