0

Good day, I want to detect the text format within my div contenteditable using arrow keys and highlight my formatting buttons.

For example: Using arrow keys, my cursor is within the word "This is me". I want to auto highlight my bold, strikethrough, and font color buttons if the selected letter/word is formatted. How will I do this?

I hope someone could help.

Thanks!

        $(function () {
            $('#editor').on('keydown', function (event) {
                if (
                    event.keyCode == 37 // arrowLeft is clicked
                    || event.keyCode == 38 // arrowUp is clicked
                    || event.keyCode == 39 // arrowRight is clicked
                    || event.keyCode == 40 // arrowDown is clicked
                ) {
                    // code here ...

                }
          });
          
        });
ul li {
 display : inline-block;
}
.btn-decorations .btn-color {
    display: block;
    width: 18px;
    height: 18px;
    border-radius: 2px;
    position: relative;
}
.btn-color-blue {
    background-color: blue;
}

.btn-color-red {
    background-color: red;
}

.btn-color-black {
    background-color: black;
}

.on {
    border: 3px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
      <p id="editor" contenteditable="true"><font><strike><b>This is me.</b></strike></font> Some test text for you to select</p>
    </div>
                        <div class="btn-area btn-area-center">
                            <ul class="btn-decorations">
                                <li>
                                    <button type="button" class="btn-ic on" id="addBold">
                                        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="17" viewBox="0 0 13 17">
                                            <g id="ic-bold" class="ic-bold" transform="translate(-5.5 -3.5)">
                                                <path id="path-1" class="path-1" data-name="path-1" d="M6,4h7.333A3.844,3.844,0,0,1,17,8a3.844,3.844,0,0,1-3.667,4H6Z" transform="translate(0)" fill="none" stroke="#777" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
                                                <path id="path-2" class="path-2" data-name="path-2" d="M6,12h8.308A3.855,3.855,0,0,1,18,16a3.855,3.855,0,0,1-3.692,4H6Z" transform="translate(0)" fill="none" stroke="#777" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
                                            </g>
                                        </svg>
                                    </button>
                                </li>
                                <li>
                                    <button type="button" class="btn-ic on" id="addStrike">
                                        <svg xmlns="http://www.w3.org/2000/svg" width="12.5" height="16.5" viewBox="0 0 12.5 16.5">
                                            <g id="ic-strike" class="ic-strike" data-name="ic-strike" transform="translate(-13.46 -4.751)">
                                                <path id="path-1" data-name="path-1" d="M25.469,12.743H19.731a7.047,7.047,0,0,1-2.227-.827A3.9,3.9,0,0,1,16.28,10.8a3.047,3.047,0,0,1-.524-1.76,3.206,3.206,0,0,1,.32-1.406A3.651,3.651,0,0,1,17.521,6.1a4.188,4.188,0,0,1,2.119-.58,3.916,3.916,0,0,1,1.784.425,4.263,4.263,0,0,1,1.548,1.371.229.229,0,0,0,.336.05A.271.271,0,0,0,23.354,7h0a4.755,4.755,0,0,0-1.725-1.526A4.366,4.366,0,0,0,19.64,5a4.611,4.611,0,0,0-3.006,1.117,4.019,4.019,0,0,0-.983,1.277,3.757,3.757,0,0,0-.374,1.643,3.594,3.594,0,0,0,.616,2.065A4.869,4.869,0,0,0,18,12.743H13.95a.259.259,0,0,0,0,.516h5.739a6.91,6.91,0,0,1,2.267.832,3.794,3.794,0,0,1,1.2,1.112,3.1,3.1,0,0,1,.51,1.76,3.209,3.209,0,0,1-.32,1.406A3.651,3.651,0,0,1,21.9,19.9a4.188,4.188,0,0,1-2.119.58A3.916,3.916,0,0,1,18,20.06a4.264,4.264,0,0,1-1.548-1.371.229.229,0,0,0-.336-.05.271.271,0,0,0-.046.362,4.756,4.756,0,0,0,1.725,1.526A4.367,4.367,0,0,0,19.78,21a4.611,4.611,0,0,0,3.006-1.117,4.017,4.017,0,0,0,.983-1.277,3.756,3.756,0,0,0,.374-1.643,3.642,3.642,0,0,0-.6-2.06,4.742,4.742,0,0,0-2.092-1.644H25.47a.259.259,0,0,0,0-.516Z" fill="#777" stroke="#777" stroke-width="0.5"/>
                                            </g>
                                        </svg>
                                    </button>
                                </li>
                                <li>
                                    <button type="button" id="addColorBlack" class="btn-add-color on">
                                        <span class="btn-color btn-color-black "></span>
                                    </button>
                                </li>
                                <li>
                                    <button type="button" id="addColorBlue" class="btn-add-color">
                                        <span class="btn-color btn-color-blue"></span>
                                    </button>
                                </li>
                                <li>
                                    <button type="button" id="addColorRed" class="btn-add-color">
                                        <span class="btn-color btn-color-red"></span>
                                    </button>
                                </li>
                            </ul>
                        </div>
  • Welcome to Stack Overflow. Your question is sort of confusing. So if the mouse cursor in in a specific HTML Element, you want those related buttons to be highlighted? Is that the case? Also why not use something like TinyMCE? – Twisty Dec 29 '21 at 01:36
  • Hi, @Twisty, I really appreciate your response. I apologize for the confusion. Yes, using arrow keys, as I focus on the formatted text inside the contenteditable (p tag), I want those related buttons to get highlighted according to the text format. Thanks for the recommendation however, as much as I want to use TinyMCE, I am not advised to use it for this project. – East Ghost Dec 29 '21 at 02:02

1 Answers1

1

Consider the following.

$(function() {
  $('#editor').on('keydown', function(event) {
    if (event.keyCode >= 37 && event.keyCode <= 40) {
      var el, active = [];
      if (document.selection) {
        el = document.selection.createRange().parentElement();
      } else {
        el = window.getSelection().anchorNode.parentNode;
      }
      while ($(el).prop("nodeName") != "P") {
        active.push($(el).prop("nodeName"));
        el = $(el).parent().get(0);
      }
      console.log(active.join(", "));
    }
  });
});
ul li {
  display: inline-block;
}

.btn-decorations .btn-color {
  display: block;
  width: 18px;
  height: 18px;
  border-radius: 2px;
  position: relative;
}

.btn-color-blue {
  background-color: blue;
}

.btn-color-red {
  background-color: red;
}

.btn-color-black {
  background-color: black;
}

.on {
  border: 3px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <p id="editor" contenteditable="true">
    <font><strike><b>This is me.</b></strike></font> Some test text for you to select</p>
</div>
<div class="btn-area btn-area-center">
  <ul class="btn-decorations">
    <li>
      <button type="button" class="btn-ic on" id="addBold">
                                        <svg xmlns="http://www.w3.org/2000/svg" width="13" height="17" viewBox="0 0 13 17">
                                            <g id="ic-bold" class="ic-bold" transform="translate(-5.5 -3.5)">
                                                <path id="path-1" class="path-1" data-name="path-1" d="M6,4h7.333A3.844,3.844,0,0,1,17,8a3.844,3.844,0,0,1-3.667,4H6Z" transform="translate(0)" fill="none" stroke="#777" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
                                                <path id="path-2" class="path-2" data-name="path-2" d="M6,12h8.308A3.855,3.855,0,0,1,18,16a3.855,3.855,0,0,1-3.692,4H6Z" transform="translate(0)" fill="none" stroke="#777" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>
                                            </g>
                                        </svg>
                                    </button>
    </li>
    <li>
      <button type="button" class="btn-ic on" id="addStrike">
                                        <svg xmlns="http://www.w3.org/2000/svg" width="12.5" height="16.5" viewBox="0 0 12.5 16.5">
                                            <g id="ic-strike" class="ic-strike" data-name="ic-strike" transform="translate(-13.46 -4.751)">
                                                <path id="path-1" data-name="path-1" d="M25.469,12.743H19.731a7.047,7.047,0,0,1-2.227-.827A3.9,3.9,0,0,1,16.28,10.8a3.047,3.047,0,0,1-.524-1.76,3.206,3.206,0,0,1,.32-1.406A3.651,3.651,0,0,1,17.521,6.1a4.188,4.188,0,0,1,2.119-.58,3.916,3.916,0,0,1,1.784.425,4.263,4.263,0,0,1,1.548,1.371.229.229,0,0,0,.336.05A.271.271,0,0,0,23.354,7h0a4.755,4.755,0,0,0-1.725-1.526A4.366,4.366,0,0,0,19.64,5a4.611,4.611,0,0,0-3.006,1.117,4.019,4.019,0,0,0-.983,1.277,3.757,3.757,0,0,0-.374,1.643,3.594,3.594,0,0,0,.616,2.065A4.869,4.869,0,0,0,18,12.743H13.95a.259.259,0,0,0,0,.516h5.739a6.91,6.91,0,0,1,2.267.832,3.794,3.794,0,0,1,1.2,1.112,3.1,3.1,0,0,1,.51,1.76,3.209,3.209,0,0,1-.32,1.406A3.651,3.651,0,0,1,21.9,19.9a4.188,4.188,0,0,1-2.119.58A3.916,3.916,0,0,1,18,20.06a4.264,4.264,0,0,1-1.548-1.371.229.229,0,0,0-.336-.05.271.271,0,0,0-.046.362,4.756,4.756,0,0,0,1.725,1.526A4.367,4.367,0,0,0,19.78,21a4.611,4.611,0,0,0,3.006-1.117,4.017,4.017,0,0,0,.983-1.277,3.756,3.756,0,0,0,.374-1.643,3.642,3.642,0,0,0-.6-2.06,4.742,4.742,0,0,0-2.092-1.644H25.47a.259.259,0,0,0,0-.516Z" fill="#777" stroke="#777" stroke-width="0.5"/>
                                            </g>
                                        </svg>
                                    </button>
    </li>
    <li>
      <button type="button" id="addColorBlack" class="btn-add-color on">
                                        <span class="btn-color btn-color-black "></span>
                                    </button>
    </li>
    <li>
      <button type="button" id="addColorBlue" class="btn-add-color">
                                        <span class="btn-color btn-color-blue"></span>
                                    </button>
    </li>
    <li>
      <button type="button" id="addColorRed" class="btn-add-color">
                                        <span class="btn-color btn-color-red"></span>
                                    </button>
    </li>
  </ul>
</div>

This expands upon the code from How to detect when a child-element of a contenteditable DIV is edited via keyboard?

If it's an arrow key, we need to then check if the parent element is P. If it is not, we need to iterate each parent element and record which elements are being applied to the Text Node.

Once you have those, you can highlight the respective buttons.

Twisty
  • 30,304
  • 2
  • 26
  • 45