Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make bold text in content editable div with raw text processing

I am trying to make font bold text with text processing instead of using execute.commands. Because I want make another functionality that not in execute.command.

Here is the code:

var selectedRange;
var selectedText = '';
let editor = document.getElementById('editor')


String.prototype.replaceBetween = function(start, end, what) {
    return this.substring(0, start) + what + this.substring(end);
};


function actionBold(e){


     let input = e.getElementsByTagName('input')[0]

    if(input != null){
        input.checked = !input.checked
    }

 
    if(selectedText.length != 0){

        let edited = editor.innerHTML.replaceBetween(selectedRange.start, selectedRange.end, `<b>${selectedText}</b>`)
        editor.innerHTML = edited
    }
}

function getSelectionCharacterOffsetWithin(element) {
    var start = 0;
    var end = 0;
    var doc = element.ownerDocument || element.document;
    var win = doc.defaultView || doc.parentWindow;
    var sel;
    if (typeof win.getSelection != "undefined") {
        sel = win.getSelection();
        if (sel.rangeCount > 0) {
            var range = win.getSelection().getRangeAt(0);
            var preCaretRange = range.cloneRange();
            preCaretRange.selectNodeContents(element);
            preCaretRange.setEnd(range.startContainer, range.startOffset);
            start = preCaretRange.toString().length;
            preCaretRange.setEnd(range.endContainer, range.endOffset);
            end = preCaretRange.toString().length;
        }
    } else if ( (sel = doc.selection) && sel.type != "Control") {
        var textRange = sel.createRange();
        var preCaretTextRange = doc.body.createTextRange();
        preCaretTextRange.moveToElementText(element);
        preCaretTextRange.setEndPoint("EndToStart", textRange);
        start = preCaretTextRange.text.length;
        preCaretTextRange.setEndPoint("EndToEnd", textRange);
        end = preCaretTextRange.text.length;
    }
    return { start: start, end: end };
}

function onMouseUp() {
 
    const sel = window.getSelection();
    var arr  = []
    for (var i = 0, len = sel.rangeCount; i < len; ++i) {
        arr.push(sel.getRangeAt(i).cloneContents().textContent);
    }
    selectedText = arr.join();

     selectedRange = getSelectionCharacterOffsetWithin(editor)
}
input{

    display: none;
}

input:checked+svg{

    background-color: rgb(194, 10, 10);
    fill: #fff;
}

label{

    cursor: pointer;
}


#editor{

    width: 50%;
    min-height: 40px;
    background-color: antiquewhite;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>


    <label  onclick="actionBold(this); return false">
        <input class="none" type="checkbox" name="0" checked>
         <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
     </label>

    <div onmouseup="onMouseUp()" id="editor" contenteditable>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Enim omnis ea, voluptas maxime perspiciatis praesentium magni repellendus earum suscipit sint. Veritatis fuga adipisci accusantium similique distinctio vero tenetur ipsam fugiat.</p>
    </div>

    <script src="script.js"></script>


</body>
</html>

I am able to get selected range and I replaced the selected string with <b> tag to get bold font. But the problem is with HTML tags are not counted in range either I don't know how to proceed this further.

I am fine with open source libraries and premium libraries but I want to study it how it works. That's why I trying it my own.

Currently I am using raw text processing. Can anyone knows How to proceed this logically to get successful text editor for bold font only? Thanks in advance.

like image 663
Mount Ain Avatar asked Nov 07 '22 09:11

Mount Ain


1 Answers

I used the following method from Range API

extractContents: to extract the selected content, so we can wrap it with bold tag.

insertNode: putting back the modified content in the same position.

let editor = document.getElementById('editor');
var preCaretRange;

function actionBold(e){
    var bold = document.createElement('b'); // created bold tag
    bold.appendChild(preCaretRange.extractContents()); // extracting and wrapping the content with tag
    preCaretRange.insertNode(bold); // insert the modified content back

}

function onMouseUp() {
    var doc = editor.ownerDocument || editor.document;
    var win = doc.defaultView || doc.parentWindow;
    preCaretRange = win.getSelection().getRangeAt(0);
}
like image 56
Pavan Kumar Jorrigala Avatar answered Nov 14 '22 21:11

Pavan Kumar Jorrigala