3

I am trying to add new element for selected element in paragraph tag. HTML code snippet as below:

 <div class="parent-bodytext">
     <p>Hello</p>
     <p>This one is</p>
     <p>Sample Text</p>
 </div>

So in above snippet I have selected "one" word from second P tag and using any event I am trying to add element to that selected text so that output will be like below:

 <div class="parent-bodytext">
     <p>Hello</p>
     <p>This <strong>one</strong> is</p>
     <p>Sample Text</p>
 </div>

So How can add this newly created "Strong" element for selected the selected text?

Avinash Jadhav
  • 1,243
  • 2
  • 12
  • 20
  • 3
    Please explain more when you need to add strong tag – Just code Jan 09 '19 at 06:43
  • @Justcode if I select any button, so that strong tag should get added to that selected text. – Avinash Jadhav Jan 09 '19 at 06:47
  • 1
    Possible duplicate of [How to make selected text bold/italic/underlined in javascript?](https://stackoverflow.com/questions/38218268/how-to-make-selected-text-bold-italic-underlined-in-javascript) – Kunal Mukherjee Jan 09 '19 at 06:48
  • I'm not 100% sure but i thing this is not possible to append strong tag with selected text if you want to do this you need to use some text editor like ckeditor https://ckeditor.com/ and use css to hide the border etc so it will show like the original page. – Yaseen Ahmad Jan 09 '19 at 06:57
  • @YaseenAhmad I am trying this part in CKEditor only. Do you aware how to achieve this with CKEditor? – Avinash Jadhav Jan 09 '19 at 07:06
  • 1
    @AvinashJadhav see this link http://jsfiddle.net/pq8yg5ke/ let me know if you need more help. – Yaseen Ahmad Jan 09 '19 at 07:30
  • @YaseenAhmad that's exactly what I am looking. Can you please elaborate the javascript code ? I did not find anything there. – Avinash Jadhav Jan 09 '19 at 07:35
  • I answer the question all code available hop it will help you. best of luck. – Yaseen Ahmad Jan 09 '19 at 07:39

3 Answers3

4

You may want to use window.getSelection for this purpose

const wrapper = document.getElementsByClassName('parent-bodytext')[0];

wrapper.addEventListener('mouseout', event => {
   const selection = window.getSelection();
   if (selection.rangeCount) {
       const replacement = document.createElement('strong');
       replacement.textContent = selection.toString();
       const range = selection.getRangeAt(0);
       range.deleteContents();
       range.insertNode(replacement);
   }
});
 <div class="parent-bodytext">
 <p>Hello</p>
 <p>This one is</p>
 <p>Sample Text</p>
 </div>
antonku
  • 7,377
  • 2
  • 15
  • 21
2

Did you want something like this?

window.onload = () => {
  function getSelectionParentElement() {
    var parentEl = null,
      sel;
    if (window.getSelection) {
      sel = window.getSelection();
      if (sel.rangeCount) {
        parentEl = sel.getRangeAt(0).commonAncestorContainer;
        if (parentEl.nodeType != 1) {
          parentEl = parentEl.parentNode;
        }
      }
    } else if ((sel = document.selection) && sel.type != "Control") {
      parentEl = sel.createRange().parentElement();
    }
    return parentEl;
  }

  function getSelectedText() {
    var text = "";
    if (typeof window.getSelection != "undefined") {
      text = window.getSelection().toString();
    } else if (
      typeof document.selection != "undefined" &&
      document.selection.type == "Text"
    ) {
      text = document.selection.createRange().text;
    }
    return text;
  }
  
  const makeBold = (selectStart, selectEnd, length, text)=>{
    let replacedText = `<strong>${text.substr(selectStart, length)}</strong>`;
    let textHalfA = text.substr(0, selectStart);
    let textHalfB = text.substr(selectEnd, text.length - 1);
    return textHalfA + replacedText + textHalfB;
  };
  
  function handleMouseUp() {
    // the selected text
    const text = getSelectedText();
    // the length of the selected content
    const selectedTextLength = text.length;
    // the parent of the selected content
    let parent = getSelectionParentElement();
    // the entire content of the parent
    let parentText = parent.innerHTML;
    // where the user's selection starts
    let selectStart = window.getSelection().getRangeAt(0).startOffset;
    // where the user's selection ends
    let selectEnd = window.getSelection().getRangeAt(0).endOffset;
    if (parent) {
      parent.innerHTML = makeBold(selectStart, selectEnd, selectedTextLength, parentText);
    }
  }

  document.onmouseup = handleMouseUp;
  document.onkeyup = handleMouseUp;
};
<p>I am a sentence.</p>

Sources would be this and this.

Also, here's a pen :)


Edit: Code's updated. The modification of the selected content should be done correctly now. Although, I have no idea how to deal with a second modification to the already modified element.(I'll update again soon. Unless, OP has an idea ;))
C.RaysOfTheSun
  • 706
  • 1
  • 6
  • 9
0

EDIT: Removed jQuery dependency You can achieve this using CSS. First, you need to separate each word with a span. Then add class strong on the span from where the event originated

window.onload = function () {
  document.getElementsByClassName("parent-bodytext")[0].onclick = function(e) {
    var tgt = e.target;
    if (tgt && tgt.nodeName === 'SPAN') {
      tgt.classList.add('strong');
    }
  };
};
.strong{
  font-weight: bold;
}
<div class="parent-bodytext">
     <p><span>Hello</span></p>
     <p><span>This</span> <span>one</span> <span>is</span></p>
     <p><span>Sample</span> <span>Text</span></p>
 </div>
Ashish
  • 4,206
  • 16
  • 45