Style text inside an HTML textarea - javascript

My problem is that I have textarea and want to find a specified string and mark all of its occurences (something similar to what regex101.com does with regex matches).
This leads me to a more general question (see my question title) and I would like to learn if the following can be applied to parts of text inside a textarea:
change font color
change background color
change font style (bold, italic)
change font size
Should I use something which already exists (like codemirror)?
I would also appreciate it if someone could explain the idea behind this (for example regex101.com has a textarea but also uses some span elements to highlight the matches)

Have you tried doing something like:
var textArea = document.getElementById("textArea");
textArea.style.color = 'Red';
textArea.style.backgroundColor = 'Black';

Related

How to make user input unaffected by span elements color style

I have some words in a content editable <div> that needs to be a different color from the rest of the text. The problem is that I don't want the user to be able to use the different color style and they should still be able to delete the blue word.
<div id="textarea" contenteditable>Hello world<span style="color: blue">!</span>
</div>
Is it possible for the users' input to be unaffected by the color style?
Instead of making the entire DIV editable, break it into separate spans, so you can specify the individual editability.
<div id="textarea"><span contenteditable>Hello world</span><span style="color: blue">!</span>
</div>
You haven't really provided enough for us to go on - eg. what are the rules which determine what is blue and what is not? Is the blue text always an exclamation mark? Does it always come at the end?
What it sounds like you will need is to build a simple lightweight code editor and apply the rules you desire. The way this works is you create a transparent editable div in the same space as a "display" div. The content of the editable textarea is invisible and the contents of the "display" div are visible. For every key stroke, you take the content of the editable textarea and write it to the "display" div and apply any custom rules. Here's a simple fiddle showing what I mean:
https://jsfiddle.net/ymdrfupb/1/
const editable = document.querySelector('.editor > [contenteditable]');
const display = document.querySelector('.editor > .display');
function setDisplayContent(text) {
// wrap any non-alphanumeric trailing characters with a blue span
display.innerHTML = text.replace(/([^\w]+)$/, '<span class="blue">$1</span>');
}
editable.addEventListener('input', (ev) => {
setDisplayContent(ev.target.innerHTML);
});
setDisplayContent(editable.innerHTML);

Find the boundaries of a text with JavaScript

My Question
Is it possible to get the boundaries of a text with JavaScript?
For example:
I want to get only the red marked area.
Why I'm Asking
I'm working on a wordcloud and want to be able to place new words inside a word's div, without overlapping the actual text.
For example:
I want to be able to place new words in the red marked areas, but my overlap-checking function won't recognize those areas as "free", since i currently use the word's div's boundaries (as shown in the black frame).
You can make a span to the places where you want to place a text, give this an id then read this id with javascript and paste the text into the span. As shown here:
Html:
<span id='mySpan'><span>
Javascript:
let span = document.getElementById("mySpan");
span.text = "example";

JavaScript apply style to content editable text

Hello I have the following code which applies a bold effect to some selected text:
richTextField.document.execCommand('Bold',false,null);
This works but what I want to do now is to be able to change the font size. If i just use:
var strUser2 = e2.options[e2.selectedIndex].value;
richTextField.document.execCommand('fontSize',false,strUser2);
it dosnt work because <font size="1/2/3/4/5/6/7"> has been removed in HTML 5. Is there a way that I could apply the style font-size:30px; to the selected text or apply a class name to the selected text ONLY that would have CSS in it? Thanks.
I don't see a way (withe execCommand) to get to a specific size, but there appears to be an increaseFontSize command that you can invoke, so:
richTextField.document.execCommand('increaseFontSize',false,strUser2);

How can I change the font color of all texts of your website using Javascript?

I learned, that there are ways to change the color of single texts. However I'd like to find out how to change the color of all texts of my website at one time.
I found the document.body.style.backgroundColor = "black"; function and hoped that there would be something similar for fonts.
Edit: I am sorry. I guess I was misleading some people. I know what CSS is ofcourse... I wanted to find a way to change the colors while using the website. So I'd like to find a way to change the CSS properties via JavaScript.
If you really want to change the color of all text on a web page using Javascript, then I would use the following code
var all = document.getElementsByTagName("*");
for (var i=0, max=all.length; i < max; i++) {
all[i].style.color = "red";
}
<div>This is text that will change colors!</div>
<div id="SomethingOtherAnswersWontChange"><span style="color:green;">Other answers will leave this text green.</span></div>
It's not exactly optimal, but it is robust. This code will change the font/text color of every element. It does this by looping through every element in the webpage and modifying the style of the elements to apply the CSS attribute "color: red;".
It is important to bear in mind that for very large web pages, this method might be a little slow, but it should get the job done.
Note: I am not 100% sure, but circumstantial CSS classes like a:hover might not be affected by this.
Use the CSS color property:
CSS
* {
color: [color-value];
}
This will change the font color of all elements using the universal (*) selector. If necessary, you may need to use the !important declaration (not recommended, but useful: see link) to override other styles.
JavaScript
document.body.style.color = [color-value];
Use .color instead of using .backgroundColor.
document.body.style.color = "red";
<div>This is text that will change colors!</div>
As stated in the comments above, you should really think about using CSS like this:
body{
color:red;
}
<div>This is text that will change colors!</div>

TinyMCE limit text on scrollerActived

I have a textarea in my rails application to collect content from user in a database. The rails application is further feeding that text to an XML-driven flex application.
The flex application has number of fixed sized containers which wraps the text inside (from the XML created by Rails app on-the-fly), but truncates the text if it exceeds the container's height. Problem is; there is no way to present the large text in XML, so it gets adjusted automatically in the compiled flex application. And the fact is; the web-based rails app and front-tier flex app are entirely disconnected in terms of having awareness of their internal events. (like in this case; rails app has no knowledge of the overflow event for flex internal containers and relying on font-size and character/line count doesn't work in this scenario!)
Therefore, I wrote a JS function to watch and rescue the textarea's overflow situation and while setting its attributes (viz; line-height, font-size, font-family, width, height... yada yada) matching that of the flex control. The complex form in rails did the trick to have dynamic number of such textarea's control being observed by the JS function.
Here is the Prototype code to handle the overflow event with the corresponding rescue code for cleanup:
var timeout;
document.observe('dom:loaded', attach_obr);
function attach_obr() {
$$('.active_text').each (function(text_element){
text_element.observe('keyup', function(e){
check_limits(text_element.id);
});
text_element.observe('change', function(e){
check_limits(text_element.id);
});
});
}
function check_limits(eyeD) {
if($(eyeD).scrollHeight > $(eyeD).offsetHeight){
// overflow occured, now the rescue code here
timeout = window.setTimeout(function() {
$("error_notice").hide();
}, 4000);
$("error_notice").show().update('There is no space left in this box, please use a new box to continue adding content');
// truncate text till the scrollbar disappears
while($(eyeD).scrollHeight > $(eyeD).offsetHeight){
$(eyeD).value = $(eyeD).value.slice(0, -1);
}
}
else {
if($("error_notice").innerHTML!=""){
$("error_notice").hide().update("");
clearTime(timeout);
}
}
}
[Note: It works with a minor flaw of truncating few more characters than expected in the last line. User can retype these letters till the end of that line. I guess this is because somehow the change in width of textarea due to the appearance of scroll-bar is effecting either the scrollHeight or offsetHeight during the process & there should be something more to the loop's condition ($(eyeD).scrollHeight > $(eyeD).offsetHeight)]
The while loop makes things bit slower, but at least it is serving the purpose. WYSIWYG is achieved. (I would love to hear any suggestion from the viewers to improve that inelegant code :O )
WYSIWYG is not achieved, in terms of rich/formatted text..
Incorporating Rich Text:
Rather than expecting from user to place tags inside the area , in the next phase, I am planning to deploy tinyMCE in my app. Now, to make the above function work with tinyMCE, I have the following code:
tinyMCE.init({
theme_advanced_buttons1 : "bold, italic, underline, strikethrough, separator, justifyleft, justifycenter, justifyright, justifyfull, separator, forecolor, backcolor",
theme:"advanced",
mode:"textareas",
plugins : "safari",
width: '360px',
height: '198px',
setup : function(ed) {
ed.onChange.add(function(ed, i) {
check_limits(ed.id);
});
}
});
The binding and firing of events is working alright. Unfortunately, the aim to control the text overflow is not working. Reason being;
a) ed.id is the id of my textarea not the interactive panel created by tinyMCE. So, the attributes like scrollHeight are offsetHeight are not getting changed for the hidden textarea control.
b) The value of textarea in this case also contains HTML code rather than the actual text. So, it is very implicit to tell what is the actual text without markup (which in our case is required when truncating the overflowed text).
My questions:
Is there a way to get the scrollHeight and offsetHeight of the control created by tinyMCE?
Is there a way to get the only-text version (without markup) of inner content of tinyMCE control?
(So, when I truncate the text in check_limits function, it doesn't effect/breaks the markup/DOM created by tinyMCE for the formatted text. In other words, I would be simulating the user action of pressing backspace on tinyMCE control in the while loop.)
Elegant way to do this whole exercise with & without tinyMCE?
Any suggestions are greatly appreciated!
First you need to know that tinymce creates a contenteditable iframe to let users edit html contents; contents from that iframe get written back to the textarea onSave. The textarea gets hidden in the rtinymce intiatilization process. The editor id is equal to the textarea id.
Here some suggestions:
1. Relevant code
var frameid = editor.id+'_ifr';
var currentiframe = document.getElementById(frameid);
var offsetHeight = currentiframe .contentDocument.body.offsetHeight;
var scrollHeight = currentfr.Document.body.scrollHeight
2. code for this (using jQuery)
var plain_text = $(editor.getBody()).text();
3. The only more efficient way to handle the while loop in the "without tinymce" case will be to slice off some more characters and follow a logarithmic approach. You slice off a bigger part of the string and then get to the final value in half-part paces. Example: You slice of 20 characters, but it fits. Then you slice off 10 characters of the original string. If it does not fit you try 15 characters and so on... this is more effectife then the while approach, but more complicated to develop.
EDIT:
It seems almost impossible to get the line number from the caret position. Problem here is that you do not know where the a text line breaks. Though it is easy to find out in which paragraph the cursor is located at (tinymce uses paragraphs to wrap text nodes).
There is a way to limit insertion in tinymce based on characters (i.e. limit can be set to 100 characters), but i guess this won't work for your use case unless you use a monospace font.
Another approach could be to set the tinymce css to set the editor window to the exact same width as your flex boxes (set the widht to the iframes body element should be sufficient). In this case it sould be easier to use the scrollHeigth approach - you would only need to find out if the heigth did change after insertion of text and then you could divied the heigth with the lineheigth to egt the line number. I suggest you write an own plugin to implement this. This is not that difficult. Here is a link to a tutorial for this.

Categories