4

I don't want to use Jquery. I want to solve this in vanilla JS. Please help me!

Description: How to make selected text bold/italic/underline on clicking a button in JavaScript?

Here is my HTML.

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="stylesheet" href="./style/style.css" />
        <link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" 
        integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" 
        crossorigin="anonymous" />
        <title>TextEditor</title>
    </head>
    
    <body>
        <header>
          <h1>Text Editor</h1>
        </header>
        <main>
            <div class="functionality">
                <div class="container">
                    <button class="btn" id="bold"><i class="fas fa-bold"></i></button>
                    <button class="btn" id="italic"><i class="fas fa-italic"></i></button>
                    <button class="btn" id="underline"><i class="fas fa-underline"></i></button>
                    <button class="btn" id="align-left"><i class="fas fa-align-left"></i></button>
                    <button class="btn" id="justify"><i class="fas fa-align-justify"></i></button>
                    <button class="btn" id="align-right"><i class="fas fa-align-right"></i></button>
                </div>
            </div>
            <div class="input-container">
                <textarea contenteditable="true" name="text-input-c1" id="text-input" rows="3"> 
                </textarea>
            </div>
        </main>
    </body>
    <script src="./script.js"></script>
    
    </html>
Björn von TRITUM
  • 525
  • 1
  • 4
  • 16
  • You cannot add styling to plain old `textarea` directly. – Ratul Sharker Apr 09 '21 at 13:02
  • For more info take a look into [mozilla's rich text editor guide](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Editable_content/Rich-Text_Editing_in_Mozilla) – Ratul Sharker Apr 09 '21 at 13:16
  • 1
    Hey Abubakar, great to see your first contribution. To get even more answers, it would be great to not just ask for help. Always provide the solution you have found so far. Or your ideas regarding the solution. Just asking for help feels like you haven't tried it for yourself. If you are unsure/ not skilled enough (right now), always ask yourself using a framework/ library like https://quilljs.com/. – Björn von TRITUM Apr 09 '21 at 15:44
  • @BjörnvonTRITUM I tried many times to solve this unfortunately I didn't succeed. I don't want to use the other libraries/framework like(quillijs/CKEditor5) to solve this because I want to solve this with javascript. :) – Abubakar Shafique Apr 09 '21 at 15:54
  • If a found any way to solve this, i will post here. :) – Abubakar Shafique Apr 09 '21 at 15:55
  • Thank you. Just to clarify. You don't want to use jquery, right? In your last comment you wrote, you don't want to use JavaScript at all. – Björn von TRITUM Apr 09 '21 at 15:57
  • Yes! I don't want the solution in Jquery but in Valina/simple JS. Sir i didn't say, "I don't want to use JavaScript at all ". – Abubakar Shafique Apr 09 '21 at 16:04
  • Why `textarea contenteditable`? – AbsoluteBeginner Apr 09 '21 at 16:59

3 Answers3

3

I think it is a possible solution.

  • I wrote a function to not replicate the code.
  • You can modify it to fit your problem and also I apply the function to just italic, bold and underline the css style. The align buttons will not work, you have to implement the logic but it's very similar as this function
  • You can try apply another function to remove the style when click again in the button.

As said before, the textarea not allow modify style of some part of the text, so I'm using span to avoid issues. I try div but I got some unlike behaviors.

function addEventEditionButton(btnId,cssProperty, cssPropertieValy) {
  let buttonTarget = document.getElementById(btnId);
  buttonTarget.addEventListener("click", function () {
    let selection = window.getSelection().getRangeAt(0);
    let selectedText = selection.extractContents();
    let span = document.createElement("span");
    try{
        span.style[cssProperty] = cssPropertieValy;
    }catch(e){
        console.trace(e);
    }    
    span.appendChild(selectedText);
    selection.insertNode(span);
  });
}

addEventEditionButton("bold", "fontWeight", "bold");
addEventEditionButton("italic", "fontStyle", "italic");
addEventEditionButton("underline", "textDecoration", "underline");
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- <link rel="stylesheet" href="./style/style.css" /> -->
    <link
      rel="stylesheet"
      href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css"
      integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p"
      crossorigin="anonymous"
    />
    <title>TextEditor</title>
    <style>
      .input-container {
        border: 1px solid black;
        width: 223px;
        height: 103px;
        overflow: scroll;
      }
    </style>
  </head>

  <body>
    <header>
      <h1>Text Editor</h1>
    </header>
    <main>
      <div class="functionality">
        <div class="container">
          <button class="btn" id="bold"><i class="fas fa-bold"></i></button>
          <button class="btn" id="italic"><i class="fas fa-italic"></i></button>
          <button class="btn" id="underline">
            <i class="fas fa-underline"></i>
          </button>
          <button class="btn" id="align-left">
            <i class="fas fa-align-left"></i>
          </button>
          <button class="btn" id="justify">
            <i class="fas fa-align-justify"></i>
          </button>
          <button class="btn" id="align-right">
            <i class="fas fa-align-right"></i>
          </button>
        </div>
      </div>
      <div contenteditable class="input-container">
        <span name="text-input-c1" id="text-input"></span>
      </div>
    </main>
  </body>
  <script src="./stackoverflow.js"></script>
</html>

Be aware in this HTML chages:

<div contenteditable class="input-container">
    <span name="text-input-c1" id="text-input"></span>
</div>
2

My suggestion:

const formatText = (tag) => {
  var start = textarea.selectionStart,
    end = textarea.selectionEnd,
    len = textarea.value.length,
    text = textarea.value.substring(start, end);
  if (text) textarea.value = textarea.value.substring(0, start) + `<${tag}>${text}</${tag}>` + textarea.value.substring(end, len);
}
form {
  display: flex;
  flex-direction: column;
}

textarea {
  width: 100%;
  height: 100px;
  margin-bottom: 20px;
}

button {
  margin-bottom: 20px;
}
<form id="form">
  <textarea id="textarea">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean venenatis justo ante, sed condimentum dui lobortis nec. Morbi ut aliquam turpis. Aliquam elementum urna diam. Morbi ullamcorper dolor ipsum, quis porttitor tortor bibendum nec. Donec imperdiet neque nec est faucibus, ac congue ligula hendrerit. Cras quis metus ullamcorper, commodo est vel, elementum nulla. In hac habitasse platea dictumst. Morbi posuere pulvinar tellus, quis tincidunt felis condimentum at. Maecenas eu molestie lorem. Nullam finibus luctus mauris, ut tincidunt diam ultrices id. Curabitur vitae vehicula mi, et tincidunt nulla. Sed vitae rhoncus sem, quis aliquet quam. Etiam dignissim lacus eget ex dictum scelerisque. Quisque id ornare odio, non placerat odio.
</textarea>
  <button type="button" onclick="formatText('i');">Italic</button>
  <button type="button" onclick="formatText('b');">Bold</button>
  <button type="button" onclick="formatText('u');">Underlined</button>
</form>

Select the text you want italic/bold/underlined, and click on the button.

AbsoluteBeginner
  • 2,160
  • 3
  • 11
  • 21
-2

You Can't style the content of a text area , Instead use Div.

and for selection AND bold you can try this .

$('#bold').click(function() {
    var selected_text = window.getSelection ? 
        "" + window.getSelection() : document.selection.createRange().text;
     console.log(selected_text);
    $("div:contains('"+selected_text+"')").html(function(_, html) {
      return html.split(selected_text).join("<b>cow</b>");
   });

});

Note: I haven't tested this

Toxy
  • 696
  • 5
  • 9