Joneron
Joneron

Reputation: 57

Why is text in between bold tags not rendered bold?

I am building a web tool for authors that follows a format we need for our backend. I didn't like a number of pre-made solutions for rich text editors as they were having way more features than I would need so I decided to parse my text through a function to detect bold using ** in the text.

I came across a regex solution here and when I used it, it detected the bold text and substituted * for <b> but displayed the tags instead of making the text between <b> and </b> bold.

I am new to HTML, CSS and JS so probably this is a simple error, but I couldn't find out how to deal with it myself...

// Tracks number of current textareas i.e. paragraphs
var element_counter = 0;

// Add Paragraph on button press
document.getElementById("addParagraph").addEventListener("click", function() {
   var textarea = document.createElement("textarea");
   var text = "Here goes your new paragraph.";
   var node = document.createTextNode(text);
   textarea.setAttribute("id", element_counter);
   //textarea.setAttribute("class", "flow-text");
   //textarea.setAttribute("oninput", "this.style.height = '';this.style.height = this.scrollHeight + 'px'");
   textarea.append(node);
   var section = document.getElementById("editor");
   section.appendChild(textarea);
   element_counter++;
   reloadPreview();
});

// Add Image on button press
document.getElementById("addImage").addEventListener("click", function() {
   var image = document.createElement("input");
   image.setAttribute("type", "file");
   image.setAttribute("id", element_counter);
   image.setAttribute("accept", "image/*");
   image.setAttribute("class", "file-field input-field");
   var section = document.getElementById("editor");
   section.appendChild(image);
   element_counter++;
});

// Remove paragraph with confirmation step on button press
var confirm = false;
document.getElementById("removeLastItem").addEventListener("click", function() {
   // Ensure there is an object to remove and wait for confirmation
   if (document.getElementById(element_counter-1) != null) {
      if (confirm === false) {
      confirm = true;
      document.getElementById("removeLastItem").innerHTML = "Confirm";
      } else {
         document.getElementById("removeLastItem").innerHTML = "Remove last item";
         var element = document.getElementById(element_counter-1);
         element.parentNode.removeChild(element);
         confirm = false;
         element_counter--;
         reloadPreview();
      }
   }
});

// Remove all with confirmation step on button press
var confirmRemoveAll = false;
document.getElementById("removeAll").addEventListener("click", function() {
   // Ensure there is an object to remove and wait for confirmation
   if (document.getElementById(element_counter-1) != null) {
      if (confirmRemoveAll === false) {
         confirmRemoveAll = true;
         document.getElementById("removeAll").innerHTML = "Confirm";
      } else {
         document.getElementById("removeAll").innerHTML = "Remove all";
         var element = document.getElementById("editor").innerHTML = ""
         confirmRemoveAll = false;
         element_counter = 0;
         reloadPreview();
      }
   }
});

// Preview on button press
document.getElementById("previewButton").addEventListener("click", reloadPreview);

// Preview current document status
function reloadPreview() {
   // Clear previous preview
   document.getElementById("preview").innerHTML = "";

   // Add elements iteratively
   var section = document.getElementById("preview");
   const id = "preview";

   for (var counter = 0; counter < element_counter; counter++) {
      var type = document.getElementById(counter).nodeName;
      // If text element
      if (type === "TEXTAREA") {
         var paragraph = document.createElement("p");
         var text = document.getElementById(counter).value;
         var richtext = boldText(text);
         paragraph.setAttribute("id", id + counter);
         paragraph.setAttribute("class", "flow-text");
         paragraph.innerHTML = richtext;
         section.appendChild(paragraph);
      }
      
      // If image element
      if (type === "INPUT") {
         // This weird structure allows to render item by item into preview and not mix up the order as onload is otherwise too slow
         (function() {
            var file = document.getElementById(counter).files[0];
            var reader = new FileReader();
            var image = document.createElement("img");
            image.setAttribute("id", id + counter);
            image.setAttribute("class", "materialboxed responsive-img");
            section.appendChild(image);

            reader.onload = function(e) {
               image.setAttribute("src", e.target.result);
            }
            reader.readAsDataURL(file);
         }())
      }
   }
}

function boldText(text){
   var bold = /\*\*(\S(.*?\S)?)\*\*/gm;
   var richtext = text.replace(bold, '<b>$1</b>');            
   return richtext;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Climate Science</title>
    <!--Used to unify web page appearance and this preview appearance-->
    <link type="text/css" href="/css/materialize.css" rel="stylesheet">
    <link type="text/css" href="/css/styles.css" rel="stylesheet"> 
    <link type="text/css" href="/css/mystyles.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons&display=swap" rel="stylesheet">

    <script href="text/javascript" src="/js/materialize.js"></script>

    <link rel="manifest" href="/manifest.json">

    <!-- IOS Support -->
    <link rel="apple-touch-icon" href="/img/icons/icon-96x96.png">
    <link rel="apple-touch-icon" href="/img/icons/icon-152x152.png">
    <meta name="apple-mobile-web-app-status-bar" content="#5368ff">
    <meta name="apple-mobile-web-app-status-bar-style" content="default">

    <meta name="theme-color" content="#5368ff">
</head>



<body class="grey lighten-5">

    <header>
        <!-- top nav -->
        <div class="navbar-fixed">
            <nav class="z-depth-2">
                <div class="nav-wrapper">
                    <ul id="nav-mobile" class="right hide-on-med-and-down">
                        <li><a href="pages/test" class="waves-effect">Log out</a></li> <!--TODO needed?-->
                    </ul>
                </div>
            </nav>
        </div>
    </header>

    <div class="container">

        <h3>Editor Area</h3>

        <p><b>Linebreaks</b> within paragraphs are currently <b>ignored</b> to follow our internal database format.</p> <!--TODO check if accurate, \n possible integratable?-->
        <!--
        <h6>Safety switch</h6>
        <div id="safetyswitch" class="switch">
            <label>
            Off
            <input type="checkbox">
            <span class="lever"></span>
            On
            </label>
        </div>
        <p>You can only remove paragraphs while the switch is deactivated!</p>

        <h6>Auto-preview</h6>
        <div id="safetyswitch" class="switch">
            <label>
            Off
            <input type="checkbox">
            <span class="lever"></span>
            On
            </label>
        </div>
        <p>The preview will load automatically while you edit your text</p>
        <br>
        -->


        <button id="addParagraph" class="waves-effect waves-light btn">Add new paragraph</button>
        <button id="addImage" class="waves-effect waves-light btn">Add new image</button>
        <button id="removeLastItem" class="waves-effect waves-light btn">Remove last item</button>
        <button id="removeAll" class="waves-effect waves-light btn">Remove all</button>
        
        <div id="editor">

            <!-- Here go all the content the author creates-->

        </div>

        <button id="previewButton" class="waves-effect waves-light btn">Update Preview</button>

        <h3>Preview</h3>

        <div id="preview">

            <!-- Here will be the preview elements when clicking the button -->



            <!--
            <form action="#">
                <p class="flow-text">What changes do you think we're already experiencing? Tap as many that apply</p>
                <p>
                    <label>
                        <input type="checkbox" />
                        <span>Raising Sea Levels</span>
                    </label>
                </p>
                <p>
                    <label>
                        <input type="checkbox" />
                        <span>Fewer Heat Waves</span>
                    </label>
                </p>
                <p>
                    <label>
                        <input type="checkbox" />
                        <span>Worse Droughts</span>
                    </label>
                </p>
                <p>
                    <label>
                        <input type="checkbox" />
                        <span>Hotter heat waves</span>
                    </label>
                </p>

                <button class="btn waves-effect waves-light btn-large" type="submit" name="action">Submit
                    <i class="material-icons right">send</i>
                </button>
            </form>
            -->

        </div>
    </div>

    <script href="text/javascript" src="js/preview.js"></script>
    <script href="text/javascript" src="js/ui.js"></script>
</body>

</html>

Upvotes: 1

Views: 1374

Answers (1)

IronMan
IronMan

Reputation: 1960

Hi so perhaps use innerHTML to insert HTML into the tag body? So instead of paragraph.append:

paragraph.innerHTML = richtext;

Upvotes: 2

Related Questions