Javascript and conditional switch, problems when saving a dynamic value

Asked

Viewed 64 times

1

Well I’m still learning a little bit more about javascript, and I’m using a little bit of jquery lately, this code is one of my most recent works, it’s a code editor.

How it works?

  • First, we have a few words stored in an arraylist and a conditional switch.

  • Second, we capture events with a function keyup and activate also another function that will capture all the value entered by the user within a field <textarea> supposedly comparing to the words of our arraylist and switch, and finally, throwing all this value to a <div>.

In algorithm it would be something like:

  • Get all the value typed in <textarea>

  • Check the words, save the ones that didn’t pass the comparison in 'x', and then save the ones that did (and that are supposed to change color) in 'y'.

  • Enter this value in the widget div specific 'x' respecting the previous rules (separating and grouping the words that will change color (plus) the ones that won’t change color).

My problem:

When a value is entered and goes through the entire verification process, the result is inserted into our <div> but soon after inserting a new word, that word that changed color earlier is lost, returning its default color.

The problem in practice:

  • The user has typed <iframe> and that result after the verification is inserted within a <div> as in the following picture:

Image 1

  • The user has typed <iframe> but also pressed the space key, and the previous value of <iframe> with its color, was lost. We have the following result:

Image 2

  • And finally, the last problem I discovered, is that nothing happens when we put another word forward or after:

image 3

Results I’m getting, summarized in an image + html output):

My results

The results I need to get (image + html output):

Image 4

Image 5

Image 6

To finish the topic, let’s go to my code:

	$( "textarea" )
  	.keyup(function() {
    var a = ["test","div","<",">","iframe"];
	var b = new RegExp(a.join("|"), 'ig');
	var c = $( this ).val();
	var d = c.replace(b, function (x) {
		switch (c) {
			case "<iframe>":
			z = '<span class="high2">'+x+'</span>';
			return z;
			break;
			case "<div>":
			z = '<span class="high2">'+x+'</span>';
			return z;
			break;
			default:
    		return '<span>'+x+'</span>';
		}
  	});
		document.getElementById("boom").innerHTML = d;
  	})
  	.keyup();
* {box-sizing: border-box;}
	.def {white-space: pre-wrap; overflow: auto; font-family: monospace; font-size: 1rem; padding: 0.5rem; caret-color: white;}
	.dark {resize: none; position: absolute; z-index: 1; color: transparent; background-color: transparent; float: left; width: 50%; height: 100px;}
	.darke {background-color: #444; color: white; position: absolute; float: left; width: 50%; height: 100px;}
	.high {color: blue; font-family: monospace; font-size: 1em;}
	.high2 {color: red; font-family: monospace; font-size: 1em;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<textarea id="target" class="dark def"></textarea>
<div id="boom" class="darke def"></div>

Thank you in advance.

1 answer

0


Tip: name your variables more clearly. a, b and c can be anything, and you will end up changing the balls at some point.

On your switch, the value being "conditioned" is the c: The full text of <textarea>.

Of course, so if your text in the <textarea> is not exactly what is in case, the substitution does not happen.

Fix the code, see below:

$( "textarea" )
.bind('input propertychange', function() {
    var keywords = ["test", "div", "<", ">", "iframe"];
    var regex = new RegExp(keywords.join("|"), 'ig');

    var text = $(this).val();
    var formatted = text.replace(regex, function (match) {
        switch (match) {
            case "<":
            case ">":
            case "iframe":
            case "div":
                z = '<span class="high2">' + match + '</span>';
                return z;
                break;
            default:
                return '<span>' + match + '</span>';
        }
    });
    
    document.getElementById("boom").innerHTML = formatted;
});
* {box-sizing: border-box;}
	.def {white-space: pre-wrap; overflow: auto; font-family: monospace; font-size: 1rem; padding: 0.5rem; caret-color: white;}
	.dark {resize: none; position: absolute; z-index: 1; color: transparent; background-color: transparent; float: left; width: 50%; height: 100px;}
	.darke {background-color: #444; color: white; position: absolute; float: left; width: 50%; height: 100px;}
	.high {color: blue; font-family: monospace; font-size: 1em;}
	.high2 {color: red; font-family: monospace; font-size: 1em;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<textarea id="target" class="dark def"></textarea>
<div id="boom" class="darke def"></div>


Note also that I include case "<" and case ">", and took the < and > of the other cases. This is because the regex match, given its Keywords, does not include these characters for the iframe and to the div, for example.

In addition, you can improve the responsiveness of your editor by changing the keydown for bind('input propertychange'), which is much faster in detecting changes in <textarea> (and detects cut and paste too, even without the keyboard!).

Obs.: I warn you that this code (not only what I’ve changed, the original as well) will be very slow for very large texts, and may need some optimization in terms of text processing.

  • Thanks! Well, I liked the way you explained the code. Fortunately I reviewed another version of this code I had done and I ended up getting where I wanted, if you want to take a look I can share the question, because a little help is always welcome. hehe!

  • In that case I would suggest creating another question, unless the problem persists x). Anyway, my recommendations remain valid: beware of the variables name, and try to change the keyup for the event I went through.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.