Alerting the selection from a textarea in CKEDITOR - javascript

i am trying to alert the selection that i choose from the textarea in CKEDITOR.
when i run, just "No text is selected." comes out.
i want to see the alert "The current selection is: "+ selection.
i think i need to change here var textarea = document.getElementById('editor1');
could anyone help me with the problem??
setup:
function ()
{
var selection = "";
var textarea = document.getElementById('editor1');
if ('selectionStart' in textarea)
{
// check whether some text is selected in the textarea
if (textarea.selectionStart != textarea.selectionEnd)
{
selection = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
}
}
else
{
// Internet Explorer before version 9
// create a range from the current selection
var textRange = document.selection.createRange();
// check whether the selection is within the textarea
var rangeParent = textRange.parentElement();
if (rangeParent === textarea)
{
selection = textRange.text;
}
}
if (selection == "")
{
alert("No text is selected.");
}
else
{
alert("The current selection is: " + selection);
}
}

To obtain the selection use the following code:
CKEDITOR.instances.youEditorInstance.getSelection().getSelectedText();
This method however returns text only (no HTML markup).
To save HTML markup, you can try something like this:
var range = CKEDITOR.instances.editor1.getSelection().getRanges()[ 0 ];
var rangeClone = range.clone();
range.collapse();
var el1 = range.getCommonAncestor( true, true );
range.splitElement( el1 );
rangeClone.collapse( true ); // to beginning
var el2 = rangeClone.getCommonAncestor( true, true );
rangeClone.splitElement( el2 );
var html = '';
var newRange = CKEDITOR.instances.editor1.getSelection().getRanges()[ 0 ];
var children = newRange.cloneContents().getChildren();
var element;
for( var i = 0 ; i < children.count() ; i++ ) {
element = children.getItem( i );
html += element.$.innerHTML ? element.getOuterHtml() : '';
}
html will store your selection HTML.

Related

Replace selected HTML only in a specific div

I want to select the HTML of whatever the user selects in a contenteditable div. I found some code to retrieve the HTML of the selection, but it's not limited to just the div.
What I want to do is copy the selected HTML, wrap tags around it, and then replace the selection with it. So, 'test' would become 'test' for instance.
<div contenteditable="true" class="body" id="bodydiv"></div>
function getSelectionHtml() {
var html = "";
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
if (sel.rangeCount) {
var container = document.createElement("div");
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
container.appendChild(sel.getRangeAt(i).cloneContents());
}
html = container.innerHTML;
}
} else if (typeof document.selection != "undefined") {
if (document.selection.type == "Text") {
html = document.selection.createRange().htmlText;
}
}
}
HI for getting content(text) inside a selected div I have create a little code you can check it out if it works for you :
$(document).ready(function(){
$(document).bind('mouseup', function(){
var content = getSelected();
content = "<b>"+content+"</b>";
$('#selected').html(content);
});
});
function getSelected(){
var t;
if(window.getSelection){
t = window.getSelection();
var start = t.focusOffset;
var end = t.baseOffset;
t = t.anchorNode.data;
t = t.slice(start, end);
} else if (document.selection) {
t = document.selection.createRange().text;
}
return t;
}
And
<div id="selected"></div>
Hope this helps.

How to save the cursor position in a Kendo UI Editor when selecting a range?

I'm using a Kendo UI Editor. I want to highlight the excess characters that are typed/pasted in the editor. This is what I've done:
$(function () {
var $editor = $('#txt-editor');
$editor.kendoEditor({
keydown: ValidateRichTextEditor
});
});
function ValidateRichTextEditor(e) {
var editor = $(e.sender.textarea),
kendoEditor = editor.data('kendoEditor'),
characters = kendoEditor.body.innerText.length,
limit = editor.data('valLengthMax');
if (characters > limit) {
var textNodes = getTextNodes(kendoEditor.body),
charCount = 0,
startNode, startOffset;
for (var i = 0, textNode; textNode = textNodes[i++];) {
var chars = charCount + textNode.length;
if (limit < chars) {
//set the text node as the starting node
//if the characters hit the limit set
startNode = textNode;
startOffset = chars - charCount;
break;
}
//add the length of the text node to the current character count
charCount += textNode.length;
}
var range = kendoEditor.createRange();
range.setStart(startNode, startOffset);
kendoEditor.selectRange(range);
kendoEditor.document.execCommand('backColor', false, '#fcc');
}
}
function getTextNodes(node) {
var textNodes = [];
//node type 3 is a text node
if (node.nodeType == 3) {
textNodes.push(node);
} else {
var children = node.childNodes;
for (var i = 0, len = children.length; i < len; i++) {
textNodes.push.apply(textNodes, getTextNodes(children[i]));
}
}
return textNodes;
}
jsfiddle
So far, the highlighting works but the cursor position is always at the position where the highlighting starts. How can I position the cursor so that it would remember the last place it was? Say for example I just keep on typing, the cursor should be at the end of the editor content. Or when I click somewhere in the middle of the content, the cursor should start where I clicked on the content.
Help on this would be greatly appreciated. Thanks!
If I am correctly interpreting your requirement, there is a much simpler solution than what you are attempting.
(function () {
var $editor = $('#txt-editor'),
limit = $editor.data('valLengthMax')
limitExceeded = false;
$editor.kendoEditor({
keyup: ValidateRichTextEditor
});
function ValidateRichTextEditor(e) {
var characters = this.body.innerText.length;
console.log('\'' + this.body.innerText + '\' : ' + this.body.innerText.length);
if (characters >= limit && !limitExceeded) {
limitExceeded = true;
this.exec('backColor', { value: '#fcc' });
}
}
})();
Update 1: This solution is a bit buggy. The backspace key causes some hiccups.
Update 2: After a lot of fiddling, you cannot trust body.innerText.length. It never returns the correct value once the background color style is executed. My reasoning is that the <span> elements that are added to the body are counted as characters and the backspace key does not remove them as would be expected.
Here is a JSBin example where you can read the console output as you type. Illogical to say the least.

Firefox triple click selection returns incorrect start and end offsets

I have this piece of code which is supposed to return the start and end offsets of the user selection:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function getSelRange() {
var selObj = window.getSelection();
var range = selObj.getRangeAt(0);
alert(range.startOffset+"-"+range.endOffset);
}
</script>
</head>
<body>
<button onclick="getSelRange()">Get the selected text!</button>
<p>Select some text!</p>
</body>
</html>
When I select some text from the p by dragging, it alerts the numbers correctly. However, when I select the entire text in the p by triple clicking on it, it alerts 0-1. Looks like in Firefox only, triple click doesn't return the selection range correctly.
How do I get the correct start and end points on triple click as well?
Firefox is returning the correct range. The problem is that your assumption that a range must have its start and end boundaries relative to a text node is incorrect.
What is happening is that Firefox is reporting the range as starting before the zeroth child node of the <p> element and ending after the first child of the <p> element. This is perfectly valid.
You could do something like the following to adjust such a range to make its boundaries lie inside the text node within the <p> element:
Demo: http://jsfiddle.net/DbmjH/2/
Code:
function adjustRange(range) {
range = range.cloneRange();
if (range.startContainer.nodeType != 3) {
var nodeAfterStart = range.startContainer.childNodes[range.startOffset];
if (nodeAfterStart && nodeAfterStart.nodeType == 3) {
range.setStart(nodeAfterStart, 0);
}
}
if (range.endContainer.nodeType != 3 && range.endOffset >= 1) {
var nodeBeforeEnd = range.endContainer.childNodes[range.endOffset - 1];
if (nodeBeforeEnd && nodeBeforeEnd.nodeType == 3) {
range.setEnd(nodeBeforeEnd, nodeBeforeEnd.data.length);
}
}
return range;
}
Check this fiddle ( Updated )
I have made it in a way that it will work on triple click when paragraph contains multiple lines.
<script>
function getSelRange() {
var selObj = window.getSelection();
var range = selObj.getRangeAt(0);
var r = document.getElementById('txt').innerHTML.split('<br>');
if (r[(range.endOffset-1)/2] == selObj) {
alert(0+"-"+r[(range.endOffset-1)/2].length);
} else if (range.startOffset >= range.endOffset) {
alert(range.startOffset + "-" + r[(range.endOffset-1)/2].length);
} else {
alert(range.startOffset + "-" + range.endOffset);
}
}
</script>
New Added Fiddle
<script>
function getSelRange() {
var selObj = window.getSelection();
var range = selObj.getRangeAt(0);
var r=document.getElementById('txt').innerHTML.split('<br>');
var selLines = selObj.toString().split('\n');
var Str = document.getElementById('txt').innerHTML;
Str=Str.replace(/<br>/g,"xzznlzzx");
var pr=selObj.toString().replace(/\r?\n/g,"xzznlzzx");
var rStr=Str.substring(0,Str.indexOf(pr));
var rSplit=rStr.split('xzznlzzx');
var prSplit=pr.split('xzznlzzx');
var countStart=0;
var countEnd=0;
var i=0;
for(;i<(rSplit.length-1);i++)
{
countStart=countStart+r[i].length;
}
for(j=0;j<(prSplit.length-1);i++,j++)
{
countEnd=countEnd+r[i].length;
}
countEnd=countEnd+countStart;
if(r[(range.endOffset-1)/2]==selObj)
{
alert((0+countStart)+"-"+(r[(range.endOffset-1)/2].length+countEnd));
}
else{
if(r[i].length<selObj.toString().length)
{
var indx = selObj.toString().indexOf(r[i]);
}
else{
var indx = r[i].indexOf(selObj.toString());
var vals=selObj.toString().length;
var res = r[i].substring(indx+vals,indx+vals+1);
if(res==""){indx=1}
else{indx=-1}
}
if(indx!=-1)
{
alert((range.startOffset+countStart)+"-"+(r[i].length+countEnd));
}
else{
alert((range.startOffset+countStart)+"-"+(range.endOffset+countEnd));
}
}
}
</script>
Note : for the above fiddles to work the string within <p> tag must be in a single line otherwise it will add the extra spaces between words to the range.

apply Highlight HTML text using javascript as in Microsoft word

I have the following code for highlighting html text using javascript:
var counter = 1;
function BindEventForHighlight() {
$('#ParaFontSize').bind("mouseup", HighlightText);
$('#ParaFontSize').unbind("mouseup", RemoveHighlight);
}
function UnBindHighlightEvent() {
$('#ParaFontSize').bind("mouseup", RemoveHighlight);
$('#ParaFontSize').unbind("mouseup", HighlightText);
}
function HighlightText() {
var text = window.getSelection();
var start = text.anchorOffset;
var end = text.focusOffset - text.anchorOffset;
range = window.getSelection().getRangeAt(0);
range1 = window.getSelection().toString();
var selectionContents = range.extractContents();
var span = document.createElement("span");
span.appendChild(selectionContents);
span.setAttribute("id", counter);
span.setAttribute("class", "highlight");
range.insertNode(span);
counter++;
}
function RemoveAllHighlights() {
var selection = document.getElementById('ParaFontSize');
var spans = selection.getElementsByTagName("span");
for (var i = 0; i < spans.length; i++) {
spans[i].className = "";
}
}
function RemoveHighlight() {
var selection = window.getSelection();
if (selection.toString() !== "" &&
selection.anchorNode.parentNode.nodeName === "SPAN") {
selection.anchorNode.parentNode.className = "";
}
else {
return false;
}
}
The HighlightText function uses range object to highlight text. and i want to save start and end of selected text into Data base, and when user get back to the same page he will see the highlighted text from previous time. also i want other scenarios as follow:
when the user highlight some text, he will be able to unhighlight all or part of this highlighted text and keep the remaining text highlighted.
the user able to clear all highlighted text in the page.
let's say i want this highlighter functions as the highlighter in MS word.
Thanks in advance
Really appreciated.

How to get the word on which a click was made in javascript

can we get the word on which a right click was made and x,y coordinates of that word ?
i tried:
document.onclick=getTextOnClick;
function getTextOnClick(e)
{
console.log(e);
if (window.getSelection) {
txt = window.getSelection();
console.log(">>>"+txt);
} else if (document.getSelection) {
// FireFox
txt = document.getSelection();
console.log(txt);
} else if (document.selection) {
// IE 6/7
txt = document.selection.createRange().text;
console.log(txt);
}
}
Now this code works if i select some text, but can i get the same when i just eight click or click on certain word ? And event object is giving me coordinates of click. can i get coordinates of the word on which the click was made ? Plz help
This can be done with pure JavaScript, assuming your container contain "simple" words only:
window.onload = function() {
var oDiv = document.getElementById("Container");
var rawHTML = oDiv.innerHTML;
var arrWords = rawHTML.split(" ");
oDiv.innerHTML = "";
for (var i = 0; i < arrWords.length; i++) {
var curWord = arrWords[i];
var curSpan = document.createElement("span");
curSpan.innerHTML = curWord;
if (i < (arrWords.length - 1))
curSpan.innerHTML += " ";
curSpan.onclick = WordClicked;
curSpan.oncontextmenu = WordClicked;
oDiv.appendChild(curSpan);
}
};
function WordClicked() {
var word = this.innerHTML;
alert("You clicked: " + word);
return false;
}
Live test case - handles both left and right click.
One way that comes to mind is putting each word in a span of its own. Apart from that, I think it will be difficult to find a solution that runs consistently on all browsers.
Thy this ?
Text ->
<div id="foo">Hello I am a text. I have no clue why I am here or
what I am good for, but I have QUOTES and other things I can offer.</div>
jQuery ->
$('#foo').contents().each(function(_, node) {
var nodelist = node.textContent.split(/\s/).map(function( word ) {
return $('<span>', {
text: word + ' ',
click: function() {
alert( $(this).text() );
}
}).get(0);
});
$('#foo').empty().append(nodelist);
});
Demo -> http://jsfiddle.net/qLuEF/

Categories

Resources