Home > Software engineering >  Change color of word containing character in input text html
Change color of word containing character in input text html

Time:10-16

I need to change the color of words starting with a special character, @word inside an input tag.

Example: Hello @John how are you?

If I type that in an input tag, the part @John should change color in the input form already.

Example:

Hello @John how are you?

It works after it's posted, but that's obviously another code. I want it to highlight words by changing color already in the input tag.

CodePudding user response:

One 5y old idea would be to:

  • Make INPUT with CSS color: transparent text, but with visible caret: caret-color: black
  • Overlay the INPUT over an underlying PRE element
  • On "input" event do some String.prototype.replace() with a regular expression that matches @mentions on the input value and replace @John with i.e: <span >@John</span>
  • Write the result as HTML to the underlying PRE element.

const colorInput = (elInput) => {
  const elPre = elInput.previousElementSibling;
  elPre.innerHTML = elInput.value.replace(/(?<=^| )@\p{L} /gu, "<span class='mention'>$&</span>");
};

document.querySelectorAll(".colorInput").forEach(el => {
  const elInput = el.querySelector("input");
  elInput.addEventListener("input", () => colorInput(elInput));
  colorInput(elInput);
});
* {
  margin: 0;
  box-sizing: border-box;
}

.colorInput {
  font: 16px/1 sans-serif;
  display: inline-block;
  border: 1px solid #888;
  position: relative;
}

/* The overlay input with transparent text but visible caret */
.colorInput>input {
  border: 0;
  width: 20rem;
  font: inherit;
  padding: 0.5rem;
  position: relative;
  background: transparent;
  /* Make text invisible */
  color: transparent;
  /* But keep caret visible */
  caret-color: black;
}

/* The underlaying DIV with colors */
.colorInput>pre {
  font: inherit;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  user-select: none;
  padding: 0.5rem;
}

.mention {
  color: fuchsia;
}
<div >
  <pre></pre>
  <input type="text" value="Hi @Daniel, how are you?">
</div>

Regarding the regex for matching mentions:

/(?<=^| )@\p{L} /gu

here's a Regex101.com example with description, and a related answer.

  • Related