Search code examples
javascriptdomuser-input

Bold/Italic/Underline User Text Input


I have a text input, I use DOM to get the text, I show the text. The problem is I want the user to be able to bold/italic/underline some words or part of the text. I was thinking about letting the user write BOLD/ITALIC/UNDERLINE around the text, search for the index of this words, and apply the changes with javascript. I can already do the first two steps, but i don't know how to apply the changes.
I search for ways to turn the text bold with javascript with document.createElement("B"); but using this method is complicated because it would be just specific words or sentences.

var bold = {}; var bld = 0;
var str = 'string BOLD of BOLD the ITALIC input text ITALIC that i UNDERLINE get UNDERLINE using dom';
var show = document.createElement("P");
//Here I use .includes() and .matchAll() to get an array with all the indexes
var regexp = new RegExp("BOLD","g");
let arraybold = [...str.matchAll(regexp)].map(a => a.index);
//ex: arraybold[0] = 7 and arraybold[1] = 15. 
for(key in arraybold) {
    bld = bld + 1;
}
regexp = new RegExp("ITALIC","g");
let arrayitalic = [...str.matchAll(regexp)].map(a => a.index);
regexp = new RegExp("UNDERLINE","g");
let arrayunderline = [...str.matchAll(regexp)].map(a => a.index);
//Here I'm suppose to create the bold/italic/underline tags on the specific words. 
for(i = 1; i <= (bld/2); i++) {
var bold[i] = document.createElement("B");
bold[i].innerText = str.slice(arraybold[i]+4, arraybold[i+1]);
//str.replace(the part of the text with the bold tag that i create);
}
show.innerText = str;
document.body.appendChild(show);

Ps: I can't use innerHTML because i will use the dom later. I would prefer to do this with vanilla javascript. The expected result:

//<p>string <strong> of </strong> the <i> input text </i> that i <u> get</u> using dom</p>

edit: using let instead of var as suggested by @cpprookie


Solution

  • Try to split string and fill an array with data which structure looks like { text: 'string', type: 'noStyle/BOLD/ITALIC/UNDERLINE' }, finally generate node based on type field.

    • First split and traverse whole string. Fill textList according to corresponding keywords(BOLD/ITALIC/UNDERLINE);
    var textList = [];
    var boldText = '';
    var italicText = '';
    var underlineText = '';
    var markAsBold = false;
    var markAsItalic = false;
    var markAsUnderline = false;
    
    var str = 'string BOLD of BOLD the ITALIC input text ITALIC that i UNDERLINE get UNDERLINE using dom';
    
    str.split(' ').forEach(s => {
      if (s === 'BOLD') {
         // match left BOLD
         if (!markAsBold) {
            markAsBold = true;
         } else {
            // match right BOLD and clear boldText;
           textList.push({
             text: boldText,
             style: 'BOLD'
           });
           boldText = '';
           markAsBold = false;
         } else if (s === 'ITALIC') {
            // same as 'BOLD' process
         } else if (s === 'UNDERLINE') {
            // same as 'BOLD' process
         } else {
            if (markAsBold) {
                boldText += boldText.length > 0 ? s : (' ' + s);
            } else if (markAsItalic) {
                italicText += italicText.length > 0 ? s : (' ' + s);
            } else if (markAsUnderline) {
                underlineText += underlineText.length > 0 ? s : (' ' + s);
            } else {
                textList.push({
                    text: s,
                    style: 'noStyle'
                })
            }
         }
      }
    })
    
    • Create node based on type in textList.
      textList.forEach(item => {
        let node;
        if (item.style === 'noStyle') {
          // create a span node
        } else if (item.style === 'BOLD') {
          // create a bold node
        } else if (item.style === 'ITALIC') {
          // create a italic node
        } else {
          // create a node and underline it with css.
        }
        // Append to parentNode at last.
      })