0

I'm trying something out, just for a bit of fun really, whereby I'm trying to emulate syntax highlighting when code is entered into a textarea on webpage.

I've written a little JS script, but It's throwing errors. "cannot set property 'color' of undefined."

To do this I have created a small array of a few example 'buzzwords' to search the entered code for. Then I have split the code string into an array and looped for matches between the two. I'm not that familiar with the split method or indeed the search method. How can I get any matches that are found to change colour on the screen in real time?

function init() {

window.setInterval(function() {
    var code = document.getElementById("texty").value;
    var buzzword = ["function","()","{","}","[","]",".getElementById",".getElementsByClassName",".style","$"];
    for(i=0; i < buzzword.length; i++) 
    {
        var testers = code.split(" ");
        for(i =0; i < testers.length; i++) 
        {
            if(buzzword[i] == testers[i]) 
            {
                code.search(testers[i]);
                code.match(testers[i]).style.color = 'blue';
            }
        }
    }
}, 10000);

}

function init() is executed onFocus of the textarea.

Any help would be appreciated, thanks!

  • 2
    Arbitrary strings don't have styles, they're not part of the DOM, they're just data. You can't apply a style to a random sub-string of a textarea's value. The code `code.match(testers[i]).style.color = 'blue';` will never work. – user229044 Sep 07 '13 at 12:52
  • 1
    continuing with what @meagar said, this is why on websites which format user input there is commonly a textarea where you give input and then another area where you can see a preview of your formatted input, for instance the stackoverflow answer textarea and preview. – Colin Sep 07 '13 at 13:13
  • that's a good point. Any ideas on code that will catch certain words in the textarea and color them blue in a seperate 'preview' div? –  Sep 07 '13 at 13:25
  • @tinkerbot, I've amended my previous wrong answer to allow you to do this. – Andy Sep 07 '13 at 15:42

2 Answers2

0

I decided to have another go at this. Quiet rightly my previous answer was shot down. Here's some code. I've not been able to jsfiddle it, but I have tested it and it works fine:

Some CSS:

<style> .blue { color: blue; } </style>

Some HTML for testing:

<div id="div"></div>
<textarea id="area" onfocus="init()">
  function writeTo() {
    var id = document.getElementById('id');
    var class = document.getElementsByClass('class');
    id.style.color = 'blue';
    var $id = $('#id');
    var array = [];
    var obj = {};
  }
</textarea>

Some Javascript. This uses a regex instead of an array. It does a find/replace on the buzzwords, wrapping them in a span with class="blue". The text is then dumped to the awaiting div:

function init() {
  var area = document.getElementById('area');
  var div = document.getElementById('div');
  var buzzword = /function|.getElementById|.getElementsByClassName|.style|\{|\}|\(|\)|\$|\[|\]/g;
  var text = area.value;
  var replacedText = text.replace(buzzword, function (selection) {
    return '<span class="blue">' + selection + '</span>';
  });
  div.innerHTML = replacedText;
}

If you want this to update in realtime (or everytime the user types something) you should bind a keyup event to the textarea to run init each time. There's more on that here.

You should get rid of your onfocus event and add this instead:

if (window.addEventListener) {
  document.getElementById('area').addEventListener('keyup', init, false);
} else {
  document.getElementById('area').attachEvent('keyup', init);
}

This will ensure that when you type in the textarea, the syntax colouring should be ok in the div. Make sure the call to your Javascript is at the bottom of your HTML page, rather that in the header otherwise it won't recognise the element.

Community
  • 1
  • 1
Andy
  • 61,948
  • 13
  • 68
  • 95
  • Thanks @Andy , your new answer works well! I changed my HTML a bit since I asked, so I had to change your solution a bit but now it works! However, When I carry on typing, the text is still blue. I need it so only the matched word is blue, and then anything not matched is default color. Do you know how to achieve this? :) –  Sep 07 '13 at 15:53
  • @tinkerbot - I've updated my answer. Hopefully the event listener code will help. – Andy Sep 07 '13 at 16:03
  • @tinkerbot, also check to see if you have any other styles called `blue` and change the class in the code to something else if you do. – Andy Sep 07 '13 at 16:24
0

I would do something like that :

var buzzwords = ['\\(\\)', 'function'];
previewDiv.innerHTML = textarea.value.replace(new RegExp(
    '(' + buzzwords.join('|') + ')', 'g'
), '<span style="color:blue">$1</span>');

Don't forget to escape special chars using two backslashes : .(){}[]$.