4

I have a textarea and when I type something, for some words the color should change.

For example, if the typed text is next one: He went to the market to buy an apple

  1. The "market" word should become green
  2. The "apple" word should become red

This is my current code:

var str = 'market';
var value = str.includes('market');

if (value == str) {
    document.getElementById("text").style.color = "green";
} else {
    document.getElementById("text").style.color = "red";
}
<textarea rows="9" cols="100" id="text" onClick="changeText();"></textarea>
Shidersz
  • 16,846
  • 2
  • 23
  • 48
  • Text area cannot have multiple colors I guess. – Maheer Ali May 11 '19 at 03:47
  • how do i achieve this any idea –  May 11 '19 at 03:47
  • To be honest its not possible so easily. You can have a `
    ` but that will not solve the problem because to change color you will need to change html. When you will change html the caret will automatically go to start. Better idea is to use some other iframes.
    – Maheer Ali May 11 '19 at 04:01
  • To color a specific word from that text you must wrap that word with a html tag. But textarea doesn't support html tag. – Nasir Khan May 11 '19 at 04:54
  • 1
    Possible duplicate of [Change Text Color if match found automatically JavaScript|HTML](https://stackoverflow.com/questions/56083692/change-text-color-if-match-found-automatically-javascripthtml) – Herohtar May 11 '19 at 06:07

3 Answers3

7

Unfortunately, you can't add markup inside a textarea, but here is an idea you could take as a starting approach, it comes from this link. The approach will be based on this:

The basic idea is to carefully position a <div> behind the <textarea>. Then JavaScript will be used to copy any text entered into the <textarea> to the <div>. A bit more JavaScript will make that both elements scroll as one. With everything perfectly aligned, we can add markup inside the <div> to give colors to some particular words, and we going to set text color to transparent on the <textarea>, completing the illusion.

Base Implementation:

// Initialization.

const colorMap = {"apple": "red", "market": "green", "banana": "orange"};
let textArea = document.getElementById("myTextArea");
let customArea = document.querySelector(".custom-area");
let backdrop = document.querySelector(".backdrop");

// Event listeners.

textArea.addEventListener("input", function()
{
    customArea.innerHTML = applyColors(textArea.value);
});

textArea.addEventListener("scroll", function()
{
    backdrop.scrollTop = textArea.scrollTop;
});

function applyColors(text)
{
    let re = new RegExp(Object.keys(colorMap).join("|"), "gi");

    return text.replace(re, function(m)
    {
        let c = colorMap[m.toLowerCase()];
        return `<spam style="color:${c}">${m}</spam>`;
    });
}
.backdrop, #myTextArea {
  font: 12px 'Open Sans', sans-serif;
  letter-spacing: 1px;
  width: 300px;
  height: 100px;
}

#myTextArea {
  margin: 0;
  position: absolute;
  border-radius: 0;
  background-color: transparent;
  color: transparent;
  caret-color: #555555;
  z-index: 2;
  resize: none;
}

.backdrop {
  position: absolute;
  z-index: 1;
  border: 2px solid transparent;
  overflow: auto;
  pointer-events: none;
}

.custom-area {
  white-space: pre-wrap;
  word-wrap: break-word;
}
<div class="container">
  <div class="backdrop">
    <div class="custom-area">
        <!-- Cloned text with colors will go here -->
    </div>
  </div>
  <textarea id="myTextArea"></textarea>
</div>

Note this is just a base approach to understand the underlying idea. But with some work on it, maybe you can get a generalized version. For example, by now, the textarea can't be resizable. But maybe you can detect that event and rezise the backdrop dinamically.

Community
  • 1
  • 1
Shidersz
  • 16,846
  • 2
  • 23
  • 48
  • i like your code but how do i pass multiple values {"apple": "red", "market": "green"} i want to pass apple bananna mango and if there is the space should be accpeted like "market city" this entire word market city should become green how do i achieve this –  May 11 '19 at 15:53
  • @fiker I have updated to read the words to colorify from the `color` object, that will solve for your first question. For your second question, maybe you can improve the generation of the regular expression to always match `market` and the next word to it. Let me think about that, and I will come with updates when I get some more time. – Shidersz May 11 '19 at 16:20
  • i like your code just find a way how to match two word combined like "market city" there is space between two words if i type in the text area the match combined word should get colored –  May 11 '19 at 17:23
  • i have one question if i create a choose file in that file text is there which ever the word matches should get color and should be displayed to textarea –  May 11 '19 at 17:31
  • @fiker I'm not understanding, can you explain better what you need? maybe with an example. – Shidersz May 11 '19 at 18:34
2

You can style the text in the textarea as a whole, but since a textarea does not have sub-elements such as or you cannot give separate text within that textarea separate styles. on the other hand if you had a separate div displaying a copy of the text you could in the innerHTML of the div assign apple to replace the word apple in the .. but the text in the textarea would remain unchanged.. possibly overlay div on top of the textarea but hidden until text is entered in the textarea. Not certain of the precise code to do that piece or if it would work. but at least it is a viable logic chain that I hope may help you find a solution.

Joe Greene
  • 61
  • 1
  • 7
0

To color a specific word from that text you must wrap that word with a html tag. But textarea doesn't support html tag.

You can do it outside of the textarea field.

Nasir Khan
  • 753
  • 1
  • 9
  • 22