I am using a content editable div as an editor for real-time collaboration purposes. I need to paint carets/cursors for each user on the client side. I am doing this by adding and removing a span on each event like keypress and click.
<span id="caret1" style="fontSize:18px color:red">|</span>
How can I make this span non-editable? So that when a user leaves his caret at a constant position and another user edits something in this same position, he can't delete this caret by backspace or select it and edit it as if it was text.
EDIT:
<span id="caret1" style="fontSize:18px color:red" contenteditable=false>|</span>
Doesn't let users write in the span at least but the users are still able to delete this span by backspace.
Couple of things
1) Your source code isn't formatted right. Too many double quotes.
"fontSize:18px" color:red"
2) The other thing is I haven't seen contentEditable as a true style, i've seen in action working more like a pseudoclass (being referenced in CSS files) or attribute to html tags, not as a style itself.
<span id="caret1" contentEditable="true" style="">
3) If neither of those work, you could try a javascript/jquery approach where deleting or backspacing to a point where there'd be two cursors on top of each other. you could add both ID's to the same span.
`<span id="caret1 caret2" style="fontSize:18px" contenteditable:"false" color:"red">|</span> `
and when caret2 does something different, move out of caret1, and create a new for caret2...
To do that, you could use a little scripting (and maybe use something like rangyInputs), and identify if the selected text has another caret in it... and also use a bit of that .on('keypress') to do validation on delete/backspace...
Related
By RTE tags I mean <b>, <i>, <u>, or <s> tags. I've been working on a RTE, and using jquery I can get the entire area to bold, but I want to be able to bold only a specific portion (think google docs, word, or any other text editor).
The mozilla site only had deprecated information, and inspecting elements on other sites (including this one) were no help to me.
I am trying to edit a content-editable <div> currently, although I'm open to switching to a text area if that works better.
//my jquery for bolding the entire thing
var bolded = false;
$("#bold").on('click', function(){
//access css of editor div, change status using a ternary
$("#editor").css("font-weight", bolded ? this.value : 'bold');
bolded = !bolded;
//log for debugging
console.log('clicked bold: ' + bolded);
});
my HTML5 for the editor. Sectioned off for formatting purposes.
<section>
<div id="editor" contenteditable="TRUE"></div>
</section>
My buttons are id'd as "bold", "itallic", "strike", and "underl", but I really just want to get one of them working so I can work from there.
EDIT
I realized that this question isn't as straightforward as I'd hoped. I have a <div>, and I would like to have multiple different formats inside of this <div>. The way I would do it logially is by inserting a <b> tag on the click of a button / keyboard command and then continuing to type from there, but I can't find any resources for it. Hope this clears that up.
EDIT 2
So as far as I can tell, the document.execCommand() still works but is predicted to be replaced by Input Events Level 2. I can't find any readable documentation for implementing this. Does anybody know how to do this?
Answer for current methodology (document.execCommand('command')):
Attaching a simple onclick() to the buttons works, where that onclick is a function that runs the aforementioned command with no particular focus:
function format(command, value){
//In use, "value" is left blank in order to do the current selection / no selection
document.execCommand(command, false, value);
}
<button onclick="format('bold')"><strong>B</strong></button>
<button onclick="format('italic')"><em>I</em></button>
Please note that this functionality WILL be deprecated, but no replacement has come up yet. When I know more, I will come back and edit this answer.
I have a contenteditable div and using keyboard shortcuts like ctrl+i the user is able to format the text. And as they type the innerHTML changes reflecting the tags i.e:
Hello <i>thanks for <br><br>for showing up<b> y'all b</b></i>
This is fine, and works well for my purposes. but the issue arises that when I go to print the html in a different div IF a user adds any other html tags, they could really mess up the application.
For instance, if they added a <script> tag or style etc.. How do I make it that the user is only allowed to add <i>, <br>, <b>, <s>, and without being able to add anything else?
Any ideas? Thank you
I think that you can use a regExpresion to avoid the "indeseables" tags. Some like
<textarea #data [(ngModel)]="value" (input)="replace(data)"></textarea>
<div [innerHtml]="valueParse">
</div>
replace(control:any)
{
this.valueParse=control.value.replace(/<(?!br|i|u)((\w+))>/gm,"<$1>")
.replace(/<\/(?!br|i|u)((\w+))>/gm,'<\/$1>');
}
See stackblitz
I have a div containing a span (the span could be a paragraph, too; I don't care):
<div id="aDiv">
<span id="aQuestion">What's next?</span>
</div>
I would like to be able to toggle the span's text's appearance between disabled and enabled. I've tried stuff along the lines of
document.getElementById('aQuestion').setAttribute("disabled", "disabled");
but haven't had any luck: The text doesn't have that grayed-out "disabled" look. When I inspect the element, I can see the attribute has been added. In fact, even if my original code looks like this:
<div id="aDiv">
<span id="aQuestion" disabled>What's next?</span>
</div>
the text doesn't appear disabled.
It seems I'm going down the wrong path, but online searches haven't resulted in a solution. Is there any way to accomplish this? I realize the concept of text being disabled doesn't exactly make sense, since they don't involve user interaction, but I need that look.
The only thing I've come up with is to use CSS, something along these lines:
CSS:
<style type="text/css">
.disableMe {
color:darkgrey;
}
</style>
The HTML:
<span id="aQuestion" class="disableMe">What's next?</span>
The JS:
document.getElementById('aSpan').classList.remove('disableMe');
This kind of gets me around the problem with the text, but some of my text spans will have adjacent spans containing bootstrap icons, and I need these to appear disabled, as well. Am I overlooking something very obvious?
Thanks in advance.
It's a span element so it doesn't have a disabled modifier, just create a css class that gives the look you want and use that.
span includes only the global attributes. So you cannot disable it. More here
I have an encapsulating span tag around some text which is all inside a content editable div.
Hello <font id="ud_First Name">Bryan</font>
The problem occurs when a user places the cursor directly to the right of the first letter inside this span tag and hits backspace to delete it, then types another character in its place.
Hello B<font id="ud_First Name">ryan</font>
While it properly deletes it and visually appears to add the new character in the right place, inspection of the source in chrome reveals that it is actually placing the new character OUTSIDE of the span which wreaks havoc on our user edits tracking.
I tried many different things but cannot get it to keep the cursor inside the span tag in this case under any circumstances.
Interestingly, HIGHLIGHTING the first character and then typing in place (replacement) keeps the cursor inside the span tag and it works as you'd expect.
Any ideas how to get the desired behavior (hopefully) simply?
I have the same problem (at least in chrome). interestingly enough, the same pattern inside a or a doesn't give the same problem.
my HTML is
<div ... contentEditable=true>
<h1>my title <span class="EMBEDDED">embedded content</span> end of title</h1>
</div>
the problem is that the user (in some cases) is not able to put the cursor before the e of "embedded content"
I don't have a proper fix now but in order to make sure the user at least sees the problem I used in css a
.EMBEDDED {
background-color: #ffb848;
display:none;
}
.EMBEDDED:before {
content:"{{"
}
.EMBEDDED:after {
content:"}}"
}
if I find a better solution I will come back
Hey Stackoverflow comunity,
There is a method str.bold() to wrap a text in <b></b> tags. This is just perfect for a tiny WYSIWYG editor (I know some will say I should take one of hundrets open source solutions, but this is for learning purposes too).
The problem is how to unbold the text.
Here is my try http://jsfiddle.net/Kxmaf/178/
I know there is editor.execCommand('bold', false, ''); but this is producing different HTML results on each browser. I need to have only <b></b>, <i></i>, <u></u>
Any help is much appreciated :)
what about looping over a selected string with javascript when pushing the specific style-button. you just could save the several tags like , , .... inside an array, and than loop through the specific string you have selected. so you even can change the style of the style-buttons when any of the tags has been found, to let the user know which style is just used. After deselecting the style just loop again through and delete the tags from string.
You need to consider the case where the user's selection spans paragraphs. For example (selection boundaries indicated with pipes):
<p>One <b>t|wo</b></p>
<p>Thr|ee</p>
To handle this, you need to wrap and all the text nodes and partial text nodes within the user's selection in <b> tags while also detecting which text nodes are already bold and leaving them alone. This is non-trivial, and document.execCommand() handles it all for you, as do the big WYSIWYG editors.
Most browsers allow switching between style modes, allowing you to choose between styling using elements such as <b> and <i> or styling using <span> elements with style attributes. You can do this using the the "StyleWithCSS" command, falling back to "UseCSS" in older browsers. The following switches commands to use the non-CSS version:
try {
if (!document.execCommand("StyleWithCSS", false, useCss)) {
// The value required by UseCSS is the inverse of what you'd expect
document.execCommand("UseCSS", false, !useCss);
}
} catch (ex) {
// IE doesn't recognise these commands and throws.
}
Finally, if you switched to using CSS classes instead of <b> etc., you could use the CSS class applier module of my Rangy library.