i'm trying to copy a text to the clipboard. But've already shown the text as selected in the modal window where it appears after an ajax call.The code is the following:
jQuery.fn.selectText = function(){
var doc = document
, element = this[0]
, range, selection
;
if (doc.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(element);
range.select();
} else if (window.getSelection) {
selection = window.getSelection();
range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
so after range = document.createRange(); i tryied inserting range.execCommand('copy'); cause i've read this tutorial about it but it doesn't mention any problem with this command. The error i'm getting is the following:
TypeError: range.execCommand is not a function
This is a mozilla tutorial about execCommand.
A range doesn't have an execCommand function, the execCommand function belongs to the document object.
Taken from the same tutorial:
When an HTML document has been switched to designMode, the document
object exposes the execCommand method which allows one to run commands
to manipulate the contents of the editable region. Most commands
affect the document's selection (bold, italics, etc), while others
insert new elements (adding a link) or affect an entire line
(indenting). When using contentEditable, calling execCommand will
affect the currently active editable element.
Related
I have a div that is contenteditable but I don't want to allow users to paste or drop formatted content into the div as this will - very likely - break the layout of the page.
The question how to handle HTML content that is pasted into such a div has already been raised several times and I was able to solve this problem as described here:
Javascript trick for 'paste as plain text` in execCommand
In one of the comments of the above question the point was raised that - in order to avoid HTML formatted content in the div at all - one needs to handle dropped content as well.
I need to support FF, Chrome, Edge and IE11. For all but IE11 I was able to implement a custom drop handler:
$("div[contenteditable=true]").on('drop', function(e) {
e.preventDefault();
var text = e.originalEvent.dataTransfer.types.indexOf && e.originalEvent.dataTransfer.types.indexOf('text/plain') >= 0 ? e.originalEvent.dataTransfer.getData('text/plain') : e.originalEvent.dataTransfer.getData('Text');
var range;
if (!document.caretRangeFromPoint) { // IE11 doesn't support caretRangeFromPoint
range = document.createRange();
range.setStart(e.currentTarget, 0);
range.setEnd(e.currentTarget, 0);
} else {
range = document.caretRangeFromPoint(e.originalEvent.clientX, e.originalEvent.clientY);
}
_insertText(text, range);
});
function _insertText(text, range) {
range.deleteContents();
var textNode = document.createTextNode(text);
range.insertNode(textNode);
range.selectNodeContents(textNode);
range.collapse(false);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<h4 style="color:red">Drag Me</h4>
<div style="border: 1px solid;" contenteditable="true">Drop here</div>
</body>
https://jsfiddle.net/m25z6ch6/
As IE11 doesn't support document.caretRangeFromPoint I already tried to manually create a range as can be seen in the above snippet like this:
range = document.createRange();
range.setStart(e.currentTarget, 0);
range.setEnd(e.currentTarget, 0);
But This only works for dropping the content at the start of the already existing text. If I want to drop content into already existing text (e.g. between "Drop" and "here" in the above example), I somehow need to compute the offset to use. But I can't figure out how to do this for IE.
Is there a way to create a range object with correct offset given the information in a drop event (e.g. x,y coordinates and/or drop target element)?
Or is there any other way to customize the dropped content in order to allow plain text only for IE11?
I have a contenteditable div, in which I have a span tag, which contains some text. How do I select the span tag and all of its contents, so when the user presses backspace or delete, the span and its contents get removed?
UPDATE: When I say select, I mean highlight. Sorry for the inconvenience.
UPDATE 2: I'm thinking along the lines of 'element.outerHTML.select()'. See if that helps.
In Firefox you have the Selection API which allows you to do that. Combine it with the DOM2 Range API and you have what you want:
var r = document.createRange();
r.selectNode(domElement);
var s = window.getSelection();
s.removeAllRanges();
s.addRange(r);
The Selection API found its way in a future standard, HTML Editing APIs, but it will be a while until it becomes available in a majority of browsers.
yesterday I answered your other question. I revised the jsfiddle accompanying that answer, please recheck it. Use shift+delete from within an editable span to bring up a dialog and to 'select' the current span.
Try this:
var span = document.getElementById("myspan");
span.onclick = function() {
var range = document.createRange();
range.selectNodeContents(span);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
};
While searching text in a document
window.find(t)
Will highlight the text in document. But how can I highlight all the text in a web page. That means how can I highlight all the text in web page as giving complete design mode text as input to the window.find()
The original intention behind this is using the trick provided by Tim Down in this page I want to check whether any formatting have been given in the document.
Please let me know if you need any other input to be more helpful.
Try this
window.find(document.body.innerText)
or
function selectElementContents(el) {
var range;
if (window.getSelection && document.createRange) {
range = document.createRange();
var sel = window.getSelection();
range.selectNodeContents(el);
sel.removeAllRanges();
sel.addRange(range);
} else if (document.body && document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(el);
range.select();
}
}
selectElementContents(document.body)
If you want all the text in the document's body, you would use document.body.innerText. If you want all the HTML in the document's body, you would use document.body.innerHTML.
I have a div tag that is contenteditable so that users can type in the div. There is a function that adds a link into the div when the user presses a button. I would like the caret to be positioned after the link so that users can continue to type. The link can be inserted many times.
Example Code:
<div id="mydiv" contenteditable="true" tabindex="-1">before link after</div>
I require this code to work in: IE, Firefox, Opera, Safari and Chrome.
Can anyone offer any help?
Assuming you have a reference to the <a> element you've inserted in a variable called link:
function setCaretAfter(el) {
var sel, range;
if (window.getSelection && document.createRange) {
range = document.createRange();
range.setStartAfter(el);
range.collapse(true);
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(el);
range.collapse(false);
range.select();
}
}
setCaretAfter(link);
I looked inside the CKEditor (http://ckeditor.com/) code and found that it has an appendBogus() function as well as inserts an extra <br><span> </span></br> that is then deleted.
The problem of course is that Gecko/IE browsers also have nuances about how <br> tags work too (i.e. whether to use \r or \n to insert into the range vs. adding an <br> element)
You can read through the _source/plugins/enterkey/plugin.js to see the different nuances with handling IE & Gecko. It seems like one big hack...
Does anyone know how to set the browser selection to a newly / independently created range? I understand how to get the text selection from the browser, and I understand how to create a range, but I don't know how to tell the browser to change the selection to the range I've created. I would have thought it would be something like "setSelection".
To be clear, I'm not trying to cause the selection of a textarea - I'm talking about p / div / ul tags etc.
I was referencing the following site (maybe it'll give you an idea?):
http://www.quirksmode.org/dom/range_intro.html
Thanks in advance for your time.
Assuming that you have a range that is a DOM Range in non-IE browsers and a TextRange in IE:
function selectRange(range) {
var sel;
if (window.getSelection) {
// Non-IE browsers
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.selection && range.select) {
// IE
range.select();
}
}