Prevent contenteditable from styling text at cursor - javascript

How to prevent content editable from styling text at cursor position. By default it get style from closest node. But how to override this behavior?
<div contenteditable> Sometext <b>bold</b>|</div>
Example on JSFIddle If you set caret (vertical bar in example) on the end of text and start typing it will be bold all the time.
My goal is to highlight some words programmatically. Bu to prevent of style user input.
Thanks.

It's a common problem for which there is no easy solution. Inserting a zero-width space character (U+200B, for example) immediately after the <b> element is one (hacky) solution.
See How to set caret/cursor position in a contenteditable div between two divs., for example.

Related

Trying to put caret (cross-browser) at the end of line on focus

Consider the following contenteditable element
<div contenteditable>
Foo bar <span contenteditable="false"></span>x</div>
DEMO
Now, the nice thing going on here is that whatever browser you take, the caret is always placed after the x if you click somewhere inside.
But, because I don't want the x at the end of the line and you remove the x the behaviour of where the caret is placed is different (safari and Edge do strange things). So, I figured that when the last line of a contenteditable ends with a span which is not editable you will have problems, so I did
<div contenteditbale>Foo Bar <span con...="false"><span></span></div>
Which actually doesn't help at all, same behaviour. It seems that the caret will not show inside an empty span
Any suggestions how to fix this?
So are you saying the caret is going inside the span, or is it a separate element? You could create a CSS Pseudo Element to position the caret where you would like it. Just use:
div::after {
content: url(caret.png);
}
Here's an updated DEMO

Contenteditable setCursorPos(elem, pos), pos = getCursorPos(elem)

Does anybody have workable solution to get or set cursor position in contenteditable div with elements inside?
What I going to do is to create twitter-like field where I will insert on # sign pressed. Problem is that browsers are pretty buggy with contenteditable attribute, so I cant rely on them for insert. So my algorithm is:
When # pressed
GetCursorPos
get content of div as a string, split it to two halves
Insert string with span between halves
Do $(div).html(new_content) - cursor will be dropped to beginning
move cursor to old_cursor + span's text length
Problem with 2 and 5. I checked following questions:
Set cursor position on contentEditable <div>
How to set caret(cursor) position in contenteditable element (div)?
Set the caret position always to end in contenteditable div
How to move cursor to end of contenteditable entity
contenteditable, set caret at the end of the text (cross-browser)
And many more... There is NO workable solution (FF, Chrome, IE) for setCursorPos(elem, pos) - everywhere is move to the end or save and restore. Also I have getCursorPosition, but sometimes in chrome it gives incorrect results, so this function appreciated also!
Thanks a lot!

How to have transparent fonts except for the 'text-caret' in a textarea?

I have a simple textarea and I need to make transparent letters while allowing the text-caret to be visible. When I apply the following rules then I get invisible caret:
textarea {
background: transparent;
opacity: 0;
}
When I type invisible text, I need to see the text-caret move.
EDIT: I need to make editor to edit td cell in table. When I click on a cell I show a textarea and start typing. On a each character letter, I insert a context in a cell. After that, I hide a textarea.
This jsFiddle DEMO uses an online tutorial method that has been slightly modified to create a non-native browser text-caret along with transparent text.
Also, this jsFiddle New Method I created handles that goal differently but isn't IE8 friendly.
Status Update: I've improved the above jsFiddle DEMO with this newer version titled:
jsFiddle New Method that's Newer!!
The above jsFiddle version now allows the inside of the text-area to be clicked and the caret will respect that clicked location. This extra functionality was made possible by a great question and answer here.
Time to throw my $0.02 in.
This is an answer to the question, as I understood it, that works, it's quick and dirty, so feel free to make suggestions. This code is untested, but I did create a working fiddle here: http://jsfiddle.net/66RXc/
<html>
<head>
<title>Testing</title>
<script type="text/javascript">
<!--
function call(val) {
document.getElementById('result').value += val.charAt(val.length - 1);
document.getElementById('result').value =
document.getElementById('result').value.substr(0, val.length);
document.getElementById('test').value =
document.getElementById('test').value.replace(/[^\^]/g, ' ');
}​
-->
</script>
</head>
<body>
<textarea name="textarea" cols="20" rows="5" id="test"
onKeyUp="call(this.value);"></textarea>
<textarea style="display:block" cols="20" rows="5" id="result" disabled>
</textarea>​
</body>
</html>
The way I approached it was every time a character is typed in textarea "test", copy it over to a hidden text box, and replace all the characters in "test" except ^ with spaces. The characters are hidden, and the carat is still there. The full text is still in the other box. You could use display:hidden instead of display:block to hide it.
This isn't exactly the best implementation in the world, just something I did quickly. You have to type kind of slow (~15-20 WPM) for it to work.
Here is a CSS3 solution for making the text, itself, transparent:
Set the color attribute to be color: rgba(0,0,0,0); for the text
The only problem is that the caret goes invisible to. I did a quick search and found out that the caret and its styling are completely at the disposal of the browser. As such, the only option that I can think of for you is to use Javascript to add a simulated caret to the end of what you are typing.
I have an idea of how to do this, but it's messy and I wouldn't exactly call it ideal - I am, however, going to write it in case it helps further someone else's idea:
add a hidden label to the page
make sure it's hidden and not display: none; (so that it has actual width)
set white-space: nowrap; to keep it all on one line)
make sure the text is styled exactly the same as the text in the textarea
add the element <span id="caret">|</span> right before the textarea (I will refer to this as the caret for the rest of the spec)
set its position to position: relative;
increase its z-index to make it overlay
shift it right in order to set it on top of where the ACTUAL caret's initial position would be
make a function to check take in the value of the textarea and check the width of the textarea against the position of the caret (lookup selectionStart if you don't know how to do this)
the problem here is that characters are not always the same length, nor are they always the same length as their counterparts in other fonts
to solve this, as text is entered into the textarea you should have it imitated in the hidden label you created in step 1
imitate only the text from the start of the textarea to the caret's current position
wrap each character (including spaces) in their own span
next you will have to call a function to compare the width of the label with the width of the textarea
if the label is less wide than the textarea, get the width of the last span in the hidden label and shift the caret to the right by that width, then move on to step 4
as this is function will be run as text is entered it will happen one character at a time
be careful here that the caret doesn't go outside the textarea when it's in its last and near last positions
if the label is wider than the textarea:
add the widths of the characters (spans) in the label one at a time until you reach the width of the textarea
shift the position of the caret down by the height of the font and back to the horizontal starting position (as the caret's position is relative, just change its left position back to (0 + offsetToACTUALCaretPosition)
use a flag (e.g. class="break") to mark the last span (character) in the previous row
call the width comparison function again
make sure that you include a condition to check for the flags that you added at the end of each "row" (if any)
if you haven't already, apply any desired CSS styles to the caret span and change the color of the textarea's text to be color: rgba(0,0,0,0);
Caveats:
this will have a lot of overhead for the tiny job it does
you will have to adjust this method to account for padding
you will have to adjust this method to add support for deleting characters and moving the carets to an earlier position (to the left)
if you leave the textarea scrollable, you will have to add support for that (also for similar settings, like static heights causing text to scroll or move off screen/out of the textarea's visible area)
As I said before, I know that this solution is very rough, but it may help someone come up with a better one.
Good luck!
Based on your edit, if you need to just hide a textarea why don't you use jQuery $('#your_id').hide();

How to position an element below a text box carret in javascript?

I have a long text field and what I want to do is that when a user types an '#' character a list of users appear just like a typical auto-complete. However I want the list of users to appear below the '#' character which could be 20-30 characters in from the start of the text box.
I've found many jQuery auto-complete plugins but none that position the list below the current caret position.
I can get the text field position using $('#textfield').position() and I can get the caret position using something like this but that gets the character index from the text value and not the pixel position.
How can I get the current carret position of a text field relative to the page in pixels in order to position an element below it?
relaying on this anwsear: Calculate text width with JavaScript
what you can do is have a div on the screen which is visible:hidden
then every time a new charecter has been entered to the textbox change the inner html of the div
so the textbox value and the div innerhtml will always be synced.
then when you want to popup your autocomplete you will add the width of the div. to the
offset left postion of the textbox.
and thats it...
and avcorse you will need that the div and the textbox will have the same font...
This jQuery plugin does what you're after:
http://plugins.jquery.com/project/caretPosition
I haven't tested it, but going by the code it looks like it creates a temporary <span> with the same content as your <textarea> (up to the cursor) and makes wild assumptions about font, line height, whitespace and word wrapping when measuring it.
You could try extending it to:
Copy the font, line height, whitespace and word wrap styles from the target <textarea>
Hide the temporary <span> without affecting the measurement by wrapping it in a <div style="height: 0; overflow: hidden;"> or positioning it absolute -9999px, -9999px
$(this).position().top ;
$(this).position().left ;
$(this).position().right ; etc... :-)

Javascript: displaying tooltip when mouse is hovered a certain word in a textarea

So I have a textarea containing text. I want to be able to display a tooltip when my mouse is hovered a certain word inside the textarea.
Is this possible at all? I would prefer to see a solution that doesn't use any third party javascript libraries.
Thanks!
If you're willing to use a "richtext" field (eg contentEditable and designMode), you can wrap the word with a <span> and attach mouseover and mouseout events to it. The big drawback with this approach is that "richtext" features that you may not want can be invoked with keyboard shortcuts in some browsers even if you don't provide an interface for them, and you'll need to filter those styles either while editing or after saving to a <textarea>.
Alternatively, you can have a hidden (but not display: none, as this will prevent accurate measurement) <div>* and update its content as the <textarea> changes, wrap the word with a <span> as in the option above, and display the tooltip if the cursor position's offset relative to the <textarea> is within bounds that would be over the <span> relative the hidden <div>. To determine position you'd probably want to start a mousemove event observer if there is a mouseover event on the <textarea>, and stop the mousemove event if there is a mouseout event on the <textarea>.
* Note: In order to ensure correct positioning, this <div> should have exactly the same font, text, line and dimensional styles as the textarea, and when mirroring the content you'll need to escape HTML special characters (&, < and >), as well as convert new lines to <br> tags.
Unless you use a contentEditable rich text editor, you would probably have to create some code that mimics the layout of a textarea and associates a word with a mouse range to determine hover over a certain text, or you could do it on the selection of a bit of text.
There is no direct way to do this for a particular word in , you can either have it for the whole textarea

Categories

Resources