I need to make a pseudo-chat addition to my website. The idea is that you write somewhere on the website, then press a button next to it and it transfers the written to a frame above. I tried doing it with textarea and even found a code how to select and copy the text, but it was also said that it works only in IE.
Does anyone have an alternative idea, because textarea seems a little iffy : /
Thanks in advance
If you want to copy text from a textarea reliably and only need to store it in a variable rather than to the user's clipboard (which seems to be what you're suggesting), the following will do it in all major browsers:
function getSelectedText(textarea) {
if (typeof textarea.selectionStart == "number") {
return textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
} else if (typeof document.selection != "undefined") {
textarea.focus();
return document.selection.createRange().text;
}
}
Related
ISSUE:
I have legacy code that runs with IE that I am trying to make cross-browser compatible. One of the features I have been struggling to get working on modern browsers (Chrome in particular) is the .select() function on Input Text. Currently users enter in a value into a field, and then hit the "find on page" button, and the relevant text will be highlighted in the table below.
Internet Explorer:
Google Chrome:
As you can see above, in Chrome, the text is not highlighted. Leading me to believe that the select() functionality is NOT supported in Chrome. However, according to https://www.w3schools.com/jsref/met_text_select.asp this function is supported by Chrome.
RELEVANT CODE:
HTML Button for text selection:
<td align="center"><input type="text" name="textSearchInput" onkeypress="if (event.keyCode == 13) {textSearch(textSearchInput.value); return false;}" size="15" maxlength="30"><button type="button" id="formSubmit2" onclick="textSearch(textSearchInput.value);"><bean:message key="fp.inventory.textSearch"/></button></td>
JavaScript for searching and highlighting that WORKS in Internet Explorer but DOES NOT work in Chrome:
var oRange = null;
function textSearch(str)
{
if ((str == null) || (str == ''))
return;
if (oRange == null)
{ // first entry, or wrap search from the end
oRange = document.body.createTextRange();
}
else
{ // move caret forward
oRange.move('character', 1);
}
var found = oRange.findText(str);
if (found)
{ // highlight and scroll to there
oRange.focus();
oRange.select();
oRange.scrollIntoView(false);
}
else
{ // see if str exists at all by going backward
found = oRange.findText(str, -1);
if (found)
{ // wrap search
oRange = null;
textSearch(str);
}
}
Is there anything else that I am missing from this? I am not the most well-versed in either HTML or JavaScript so I could be missing something basic..
createTextRange is not supported in Chrome
http://help.dottoro.com/ljouisvm.php
You'll need to detect the browser and use an alternative.
This may work:
https://developer.mozilla.org/en-US/docs/Web/API/Document/createRange
I'm trying to allow the user to paste an image into a div. The problem is that I need it work in Firefox.
From what I've read, Firefox since version 13 (I think) doesn't allow JavaScript access to the clipboard, and event.clipboard doesn't exist in it. I know it can be done because Gmail and Yahoo alow it even in Firefox.
I just want it to work in anyway posible, be with jQuery, JavaScript, HTML5, it doesn't matter as long as it works in the latest Firefox. (No Flash though).
I used the code from this question for my cross-browser paste implementation.. it works in all browsers I have tested (scroll down for the actual solution/code). It should be noted that event.clipboardData expires immediately after the paste event has completed execution.
I went ahead and quadruple checked that this does work in Firefox version 19 (I don't have 13 available, but it sounds like this question was about degradation of a feature in newer versions).
Below is the answer, quoted from Nico Burns:
Solution
Tested in IE6+, FF 3.5+, recent-ish versions of Opera, Chrome, Safari.
function handlepaste (elem, e) {
var savedcontent = elem.innerHTML;
if (e && e.clipboardData && e.clipboardData.getData) {// Webkit - get data from clipboard, put into editdiv, cleanup, then cancel event
if (/text\/html/.test(e.clipboardData.types)) {
elem.innerHTML = e.clipboardData.getData('text/html');
}
else if (/text\/plain/.test(e.clipboardData.types)) {
elem.innerHTML = e.clipboardData.getData('text/plain');
}
else {
elem.innerHTML = "";
}
waitforpastedata(elem, savedcontent);
if (e.preventDefault) {
e.stopPropagation();
e.preventDefault();
}
return false;
}
else {// Everything else - empty editdiv and allow browser to paste content into it, then cleanup
elem.innerHTML = "";
waitforpastedata(elem, savedcontent);
return true;
}
}
function waitforpastedata (elem, savedcontent) {
if (elem.childNodes && elem.childNodes.length > 0) {
processpaste(elem, savedcontent);
}
else {
that = {
e: elem,
s: savedcontent
}
that.callself = function () {
waitforpastedata(that.e, that.s)
}
setTimeout(that.callself,20);
}
}
function processpaste (elem, savedcontent) {
pasteddata = elem.innerHTML;
//^^Alternatively loop through dom (elem.childNodes or elem.getElementsByTagName) here
elem.innerHTML = savedcontent;
// Do whatever with gathered data;
alert(pasteddata);
}
<div id='div' contenteditable='true' onpaste='handlepaste(this, event)'>Paste</div>
Explanation
The onpaste event has the handlepaste function attached to it, and passed two arguments: this (i.e. a reference to the element that the event is attached to) and event which is the event object.
The handlepaste function:
The first line simply saves the content of the editable div to a variable so it can be restored again at the end.
The if checks whether the browser is an webkit browser (chrome or safari), and if it is it sets contents of the editable div to the data being pasted. It then cancels the event to prevent webkit pasting anything twice. This is because webkit is awkward, and won't paste anything if you simply clear the div.
If it is not a webkit browser then it simply clears the editable div.
It then calls the waitforpastedata function
The waitforpastedata function:
This is necessary because the pasted data doesn't appear straight away, so if you just called processpaste straight away then it wouldn't have any data to process.
What it does is check if the editable div has any content, if it does then calls processpaste, otherwise it sets a timer to call itself and check again in 20 milliseconds.
The processpaste function:
This function saved the innerHTML of the editable div (which is now the pasted data) to a variable, restores the innerHTML of the editable div back to its original value, and the alert the pasted data. Obviously in a real usage scenario you would probably want to something other than just alert data, you can do whatever you like with it from here.
You will probably also want to run the pasted data through some kind of data sanitising process. This can be done either while it is still in the editable div, or on the extracted string.
In a real sitution you would probably want to save the selection before, and restore it afterwards (Set cursor position on contentEditable <div>). You could then insert the pasted data at the position the cursor was in when the user initiated the paste action.
P.S. The combination of this code, IE <= 8 and jsfiddle doesn't seem to work, but it does work in ie <= 8 in a non-jsfiddle environment.
I have a textarea and a button on a form. The textarea may already have some text in it. I would like the cursor to move to the last position in the text area when the button is clicked.
Is this possible?
xgMz's answer was best for me. You don't need to worry about the browser:
var html = $("#MyTextArea").val();
$("#MyTextArea").focus().val("").val(html);
And here's a quick jQuery extension I wrote to do this for me next time:
; (function($) {
$.fn.focusToEnd = function() {
return this.each(function() {
var v = $(this).val();
$(this).focus().val("").val(v);
});
};
})(jQuery);
Use like this:
$("#MyTextArea").focusToEnd();
By “the last position”, do you mean the end of the text?
Changing the ‘.value’ of a form field will move the cursor to the end in every browser except IE. With IE you have to get your hands dirty and deliberately manipulate the selection, using non-standard interfaces:
if (browserIsIE) {
var range= element.createTextRange();
range.collapse(false);
range.select();
} else {
element.focus();
var v= element.value();
element.value= '';
element.value= v;
}
Or do you mean put the cursor back to the place it was previously, the last time the textarea was focused?
In every browser except IE, this will already happen just by calling ‘element.focus()’; the browser remembers the last cursor/selection position per input and puts it back on focus.
This would be quite tricky to reproduce in IE. You would have to poll all the time to check where the cursor/selection was, and remember that position if it was in an input element, then fetch the position for a given element when the button was pressed and restore it. This involves some really quite tedious manipulation of ‘document.selection.createRange()’.
I'm not aware of anything in jQuery that would help you do this, but there might be a plugin somewhere perhaps?
You can also do this:
$(document).ready(function()
{
var el = $("#myInput").get(0);
var elemLen = el.value.length;
el.selectionStart = elemLen;
el.selectionEnd = elemLen;
el.focus();
});
This code works for both input and textarea. Tested with latest browsers: Firefox 23, IE 11 and Chrome 28.
jsFiddle available here: http://jsfiddle.net/cG9gN/1/
Source: https://stackoverflow.com/a/12654402/114029
You could use this https://github.com/DrPheltRight/jquery-caret
$('input').caretToEnd();
This is what I use for textareas inside my onclick or other events and seems to work fine for FireFox and IE 7 & 8. It positions the cursor at the end of the text instead of the front.
this.value = "some text I want to pre-populate";
this.blur();
this.focus();
To set mouse focus and move cursor to end of input. Its work in every browser, Its just simple logic here.
input.focus();
tmpStr = input.val();
input.val('');
input.val(tmpStr);
I modified #mkaj extension a little to support default value
; (function($) {
$.fn.focusToEnd = function(defaultValue) {
return this.each(function() {
var prevValue = $(this).val();
if (typeof prevValue == undefined || prevValue == "") {
prevValue = defaultValue;
}
$(this).focus().val("").val(prevValue);
});
};
})(jQuery);
// See it in action here
$(element).focusToEnd("Cursor will be at my tail...");
I'm trying to build a safari extenstion (mostly for learning purposes) that creates a delicious bookmark, when the user right clicks on a link. I've watched the WWDC Creating a Safari Extension video and everything is working fine.
Except that i don't have a clue how to find out if the user clicked on a link (or just some text) and if so, get it's url and title. What i got so far is this:
document.addEventListener("contextmenu", handleContextMenu, false);
function handleContextMenu(event){
safari.self.tab.setContextMenuEventUserInfo(event,getSelection().toString());
}
But this obviously only gives me a string of the selection. Now, according to the Safari Reference Library getSelection() returns a DOMSelection object. But even there i'm not able to spot a method that gives me a handle on the selected link.
As you might notice, i'm fairly new to this whole javascript and DOM stuff, so please excuse if this is an obvious question :)
Ciao,
Sven
On a simple right-click, the selection will be set inside the anchor link. This means you will have its text node selected, but the link node itself won't be. Therefore, it's useless to try to find a link inside a selection.
You can use DOMSelection's focusNode to get the last selected text node and check its ancestors until you wind up to an <a> element. That should do about what you want.
var link = null;
var currentElement = event.getSelection().focusNode;
while (currentElement != null)
{
if (currentElement.nodeType == Node.ELEMENT_NODE && currentElement.nodeName.toLowerCase() == 'a')
{
link = currentElement;
break;
}
currentElement = currentElement.parentNode;
}
// link is now an <a> element if the user selected a link's contents
zneak's answer did not work for me, so I worked with event.target instead of the selection:
var link = evt.target;
// get parent node in case of text nodes (old safari versions)
if(link.nodeType == Node.TEXT_NODE) {
link = link.parentNode;
}
// if for some reason, it's not an element node, abort
if(link.nodeType != Node.ELEMENT_NODE) {
return;
}
// try to get a link element in the parent chain
while(link != null &&
currentElement.nodeType == Node.ELEMENT_NODE &&
link.nodeName.toLowerCase() != "a") {
link = link.parentNode;
}
if(link) {
// do stuff
}
I want to inactive selecting & copying text in html page.
when I used Javascript & inactive right click user can use Ctrl+V!!
You can't. Don't even try. Don't annoy your users.
If you put it publicly on the web, it can be copied. Technically, it already is copied as soon as the user sees it. As colithium pointed out, all the techniques can be circumvented. Heck, you can look at the source code. You can curl the raw data from the command line, no JS/IMG/layer hack can prevent that.
There is no full proof solution. You can play javascript games (easy to turn off). You can place invisible layers about the text so it can't be selected easily (easy to view source). You can use images instead of text (just bad).
While I agree in principle with the other posters that trying to do this may annoy the user, sometimes a manager or customer demands that this be done, and so an answer needs to be supplied.
Check out this page on www.dynamicdrive.com that will supply you with a few JavaScripts towards this end. Specifically see "Disable Text Select Script" and "No right click script".
Disable Text Select Script:
/***********************************************
* Disable Text Selection script- © Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/
function disableSelection(target){
if (typeof target.onselectstart!="undefined") //IE route
target.onselectstart=function(){return false}
else if (typeof target.style.MozUserSelect!="undefined") //Firefox route
target.style.MozUserSelect="none"
else //All other route (ie: Opera)
target.onmousedown=function(){return false}
target.style.cursor = "default"
}
//Sample usages
//disableSelection(document.body) //Disable text selection on entire body
//disableSelection(document.getElementById("mydiv")) //Disable text selection on element with id="mydiv"
No right click script:
//Disable right mouse click Script
//By Maximus (maximus#nsimail.com) w/ mods by DynamicDrive
//For full source code, visit http://www.dynamicdrive.com
var message = "Function Disabled!";
///////////////////////////////////
function clickIE4() {
if (event.button == 2) {
alert(message);
return false;
}
}
function clickNS4(e) {
if (document.layers || document.getElementById && !document.all) {
if (e.which == 2 || e.which == 3) {
alert(message);
return false;
}
}
}
if (document.layers) {
document.captureEvents(Event.MOUSEDOWN);
document.onmousedown = clickNS4;
} else if (document.all && !document.getElementById) {
document.onmousedown = clickIE4;
}
document.oncontextmenu = new Function("alert(message);return false")