0

So I have made this webpage wherein it is a pseudo RTF editor that inserts data into the database. Insert into php the html in a div

I am having a problem when it comes to text styling the text typed after selecting a text style from a drop down. I would want it to be like word wherein after clicking on a particular text style, it would start typing using that said text style but not affecting rest of the text inside of a div. Codepen



    <style>
        #fake_textarea {
  width: 100%;
  height: 200px;
  border: 1px solid red;
}
<!-- Add css to modify the text -->
#jBold {
  font-weigth: bold;
}
#jItalic{
    font-style:italic;
}
#jUnderline{
    text-decoration: underline;
}
#jLT{
    text-decoration: line-through;
}
    </style>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js"></script>
<body>
    <!-- Put buttons here to modify the format -->
    <div>

    <select id="select_font" onchange="changeFont(this);">
  <option value="Arial">Arial</option>
  <option value="Sans Serif" selected>Sans Serif</option>
  <option value="Comic Sans MS">Comic Sans MS</option>
  <option value="Times New Roman">Times New Roman</option>
  <option value="Courier New">Courier New</option>
  <option value="Verdana">Verdana</option>
  <option value="Trebuchet MS">Trebuchet MS</option>
  <option value="Arial Black">Arial Black</option>
  <option value="Impact">Impact</option>
  <option value="Bookman">Bookman</option>
  <option value="Garamond">Garamond</option>
  <option value="Palatino">Palatino</option>
  <option value="Georgia">Georgia</option>
</select>
<select id="select-size" onchange="changeSize(this);">
<option value="4">4</option>
  <option value="8">8</option>
  <option value="12">12</option>
  <option value="16">16</option>
  <option value="20">20</option>
  <option value="24">24</option>
  <option value="28">28</option>
  <option value="32">32</option>
  <option value="36">36</option>
  <option value="40">40</option>
  <option value="44">44</option>
  <option value="48">48</option>
  <option value="52">52</option>
  <option value="56">56</option>
  <option value="58">58</option>
</select>
<button id="jBold"><b>B</b></button><button id="jItalic"><i>I</i></button><button id="jUnderline">U</button><button id="jSuperScript">A<sup>A</sup></button><button id="jSubScript">A<sub>A</sub></button>
<button id="jLT">A</button>
<div>
    <!-- Add a form -->
    <form method="post" action="postcontent.php"  id="contentform">
    <!-- Add some hidden input in order for the form to submit some sort of value -->
        <input type="hidden" name="content" id="hiddeninput" />
        <!-- Add a place to insert the content -->
        <div id='fake_textarea' contenteditable>
              Select some text and click the button to make it bold...
              <br>Or write your own text
        </div>
        <!-- Add a submit button-->
        <button id="submit">Submit</button>
    </form>
    <!-- Script to make a selected text bold-->
        <script type="text/javascript">
            $(document).ready(function() {
                $('#jBold').click(function() {
                    document.execCommand('bold');
                });
            });

        </script>
        <!-- Script to make a selected text italic-->
           <script type="text/javascript">
           $(document).ready(function() {
                $('#jItalic').click(function() {
                    document.execCommand('italic');
                });
            });

        </script>
        <!-- Script to make add an underline-->
           <script type="text/javascript">
           $(document).ready(function() {
                $('#jUnderline').click(function() {
                    document.execCommand('underline');
                });
            });

        </script>
        <!-- Script to make make selected text a superscript-->
           <script type="text/javascript">
           $(document).ready(function() {
                $('#jSuperScript').click(function() {
                    document.execCommand('superscript');
                });
            });

        </script>
        <!-- Script to make make selected text a subscript-->
           <script type="text/javascript">
           $(document).ready(function() {
                $('#jSubScript').click(function() {
                    document.execCommand('subscript');
                });
            });

        </script>
                <!-- Script to add a line-through-->
           <script type="text/javascript">
           $(document).ready(function() {
                $('#jLT').click(function() {
                    document.execCommand('strikeThrough');
                });
            });

        </script>




        <!-- Changes the font type -->
        <script  type="text/javascript">
        function changeFont(font) {
            var sel = window.getSelection(); // Gets selection
            if (sel.rangeCount) {
            // Creates a new element, and insert the selected text with the chosen font inside
            var e = document.createElement('span');
            e.style = 'font-family:' + font.value + ';'; 
            e.innerHTML = sel.toString();

            // https://developer.mozilla.org/en-US/docs/Web/API/Selection/getRangeAt
            var range = sel.getRangeAt(0);
            range.deleteContents(); // Deletes selected text…
            range.insertNode(e); // … and inserts the new element at its place
            }
        }
        </script>
        <!-- Changes the font size -->
        <script  type="text/javascript">
        function changeSize(size) {
        var sel = window.getSelection(); // Gets selection
            if (sel.rangeCount) {
            // Creates a new element, and insert the selected text with the chosen font inside
            var e = document.createElement('span');
            e.style = 'font-size:' + size.value + 'px;'; 
            e.innerHTML = sel.toString();

            // https://developer.mozilla.org/en-US/docs/Web/API/Selection/getRangeAt
            var range = sel.getRangeAt(0);
            range.deleteContents(); // Deletes selected text…
            range.insertNode(e); // … and inserts the new element at its place
            }   
        }

        </script>

        <!-- Script to add value to the hidden input then submits it-->
        <script  type="text/javascript">

        $( "#submit" ).click(function() {

            var htmlString = $( "#fake_textarea" ).html();
            $('#hiddeninput').val(htmlString);
            // Submit the real form
            $('#contentform').submit();
        });

        </script>
</body>
  • I can't give you a good example right now, but I think what you need to do is wrap the selected text in a div and set that div's font-style to the selected content. You will have probably have to search around to get some more information on that though. – nrayburn-tech May 08 '20 at 01:48
  • So I would need to insert it with a css right? – Xe Pueblos May 08 '20 at 12:12
  • Yes, that’s basically all you’re doing. To change the font of the element as you type, you have to change the font type of the parent element, or you may be able to listen for keyup/keydown events and set the font type at that time. I’ll see if I can make an example later today. – nrayburn-tech May 08 '20 at 12:23
  • thanks. I have been trying in modifying my code yet it requires it to be selected and changed initially before it they can start typing in another font type which is an unnecessary extra step. – Xe Pueblos May 08 '20 at 12:47
  • I haven't been able to figure out a way to do it. What you need is every element inside of your content to have a specified style. This way anytime you change the text styling, it doesn't affect the rest. However, I am not really sure how/when to apply the styling so that it works in a robust way. – nrayburn-tech May 08 '20 at 19:43
  • I found this fiddle. Would this work? [link](https://jsfiddle.net/v127c14p/) – Xe Pueblos May 09 '20 at 02:22

2 Answers2

0

Here is the general idea of what has to be done, so that you can have different styling inline.

You need to wrap all of your text that is inside of your div that is contenteditable inside another element, I chose span. The span then needs to have all of the styling you are controlling applied to it. Then, you need to listen for all methods of inputting text into the editable div. Anytime text is entered, you need to check if the current styling filters that are applied match the previous text element. You can use window.getSelection().anchorNode.parentNode to get the previous element's parent. If it matches, you just append the new text to the previous element. If it does not match, you create a new element with the appropriate styling.

Here is a link with an example where font-size, font-family, and color can be controlled. https://jsfiddle.net/nrayburn/50uhdwfg/100/

There are a few issues with the example, but I wanted to get you somewhere to start. The caret does not move with the text as you type. This is because event.preventDefault() is called, so it doesn't go through the normal process to move it. The other issue is that the new elements aren't inserted at the correct place, you just need to figure out the best way to insert into the proper spot. It also does not handle inserting text anywhere except the end of a previous element. Editing text would need to check if the styling changes. If it does, then it needs to split the text on both sides into new spans with the old formatting and create a new span in the middle with the current formatting.

nrayburn-tech
  • 935
  • 1
  • 4
  • 10
  • so I have been toying with the code that you gave me and it would seem to work though the problem is that it would always double what input on the right side of it. Any ideas? [codepen](https://codepen.io/goldenowl/pen/XWmEvEe) – Xe Pueblos May 09 '20 at 07:53
  • You’re not calling event.preventDefault(), so the original key event is processed adding a character. And then, the span is appended with the character as well. – nrayburn-tech May 09 '20 at 15:04
  • I added that and the end result is that the insertion point stays the same for some reason. – Xe Pueblos May 10 '20 at 01:04
  • Correct. That’s the issue I was having. You may want to post a new question with how to set the caret position. I couldn’t figure it out. – nrayburn-tech May 10 '20 at 01:47
  • alright so I have figured it out. I am still trying to figure out the anything in excess of 7 for execcomand but I have made it so that it can be edited on the fly. [Codepen](https://codepen.io/goldenowl/pen/XWmEvEe) – Xe Pueblos May 10 '20 at 11:12
  • It looks like it is limited to 7. That being said, I would recommend not using execcommand as it is now marked as obsolete. There are most likely alternative ways to accomplish what you are doing with css. https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand – nrayburn-tech May 10 '20 at 17:11
  • I see though I do not see an alternative to it. As per [Mozilla](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Editable_content) they still use and reference editable content using execcomand and that document is not obsolete. There are [discussions](https://stackoverflow.com/questions/60581285/execcommand-is-now-obsolete-whats-the-alternative) as to what to use include that with alternatives – Xe Pueblos May 11 '20 at 00:25
0

So I have solved the change font style on the fly problem and but I am still trying to figure out that problem when it comes to anything bigger than 36.

codepen

I added

 document.execCommand("fontName", false, font);

at the end of my change font script

function changeFont(font) {

        var sel = window.getSelection(); // Gets selection
        if (sel.rangeCount) {
        // Creates a new element, and insert the selected text with the chosen font inside
        var e = document.createElement('span');
        e.style = 'font-family:' + font.value + ';'; 
        e.innerHTML = sel.toString();

        // https://developer.mozilla.org/en-US/docs/Web/API/Selection/getRangeAt
        var range = sel.getRangeAt(0);
        range.deleteContents(); // Deletes selected text…
        range.insertNode(e); // … and inserts the new element at its place
        }
             document.execCommand("fontName", false, font);

    }

as for changing the font size, I inserted

                      if(size=="8")
        {
            document.execCommand("fontSize", false, "1");
        }
      if(size=="10")
        {
            document.execCommand("fontSize", false, "2");
        }           
                  if(size=="12")
        {
            document.execCommand("fontSize", false, "3");
        }
      if(size=="14")
        {
            document.execCommand("fontSize", false, "4");
        }

                if(size=="18")
        {
            document.execCommand("fontSize", false, "5");
        }
                  if(size=="24")
        {
            document.execCommand("fontSize", false, "6");
        }  
        if(size=="36")
        {
            document.execCommand("fontSize", false, "7");
        }

at the end of it thus making my change font size script

function changeSize(size) {

    var sel = window.getSelection(); // Gets selection

        if (sel.rangeCount) {
        // Creates a new element, and insert the selected text with the chosen font inside
        var e = document.createElement('span');
        e.style = 'font-size:' + size.value + 'px;'; 
        e.innerHTML = sel.toString();

        // https://developer.mozilla.org/en-US/docs/Web/API/Selection/getRangeAt
        var range = sel.getRangeAt(0);
        range.deleteContents(); // Deletes selected text…
        range.insertNode(e); // … and inserts the new element at its place
        }   
                  if(size=="8")
        {
            document.execCommand("fontSize", false, "1");
        }
      if(size=="10")
        {
            document.execCommand("fontSize", false, "2");
        }           
                  if(size=="12")
        {
            document.execCommand("fontSize", false, "3");
        }
      if(size=="14")
        {
            document.execCommand("fontSize", false, "4");
        }

                if(size=="18")
        {
            document.execCommand("fontSize", false, "5");
        }
                  if(size=="24")
        {
            document.execCommand("fontSize", false, "6");
        }  
        if(size=="36")
        {
            document.execCommand("fontSize", false, "7");
        }
    }

I am hoping to find a way to increase the font size or some other way than adding document.execCommand("fontSize", false, "7"); at the end of it.