Apply class to button which execCommand on contentEditable div

Viewed 959

Is there a built in way of keeping a button active when it execute a execCommand on a content editable div ?

example :

<input type="button" onclick="doRichEditCommand('bold');" value="B"/>

function doRichEditCommand(command){
    document.execCommand(command, null, false);
}

I'd like my button to remain active when the carret is within something where document.execCommand(command, null, false); has been applied. I suppose it's doable by checking the parent elements but if there is a built in way it would be better.

In other words I'd like my bold button to be orange when the carret is somewhere which should be bold.

3 Answers

It's doable, but it's really annoying.

Every time the contenteditable changes you call document.queryCommandState() to find the state of the text where the caret is, and then update the button class to match. So something like:

let div = document.getElementById("myContentEditable");
div.oninput = () => {
  if (document.queryCommandState('bold')) {
    console.log("bold!");
  } else {
    console.log("not bold.");
  }
  return false;
};

From there you can apply or remove a style from your bold button to indicate whether the cursor's in a bold section or not. Repeat for the other styles.

The annoying part is that you need to update the button state on several different events. This seems fairly exhaustive to me:

div.oninput = div.onselect = div.onchange = div.onkeyup = eventhandler;

...but I could be wrong.

This is what I achieved:

JS

function format(command) {
    document.execCommand(command, false);
    const button = document.getElementById(command);
    button.classList.toggle("button--active");
 }

HTML

<button id="bold" onclick="format(this.id)">Bold</button>

SCSS

button {
    //Whatever you want
    &--active {
            //Whatever you want
    }
}

However, it works for general writing. If you select text and apply an effect, the button will be kept active.

Related