This question already has answers here:
How do I copy to the clipboard in JavaScript?
(27 answers)
Closed 4 years ago.
I need to copy any selection from a webpage to the clipboard, it can be on a div, text input, password input, span, etc.
I have the following function that does this for me, but the challenge is have the returned value from the function to be set on the clipboard
const getSelectionText = () => {
let text = "";
let activeDomElement = document.activeElement;
let activeDomElementTagName = activeDomElement ? activeDomElement.tagName.toLowerCase() : null;
if (
(activeDomElementTagName === 'textarea') || (activeDomElementTagName === 'input' &&
/^(?:text|search|password|tel|url)$/i.test(activeDomElement.type)) &&
(typeof activeDomElement.selectionStart === "number")
) {
text = activeDomElement.value.slice(activeDomElement.selectionStart, activeDomElement.selectionEnd);
} else if (window.getSelection) {
text = window.getSelection().toString();
}
return text;
}
Any idea, or links to resources would be helpful, thanks
Have a look at the example from w3schools.It is a basic example.
https://www.w3schools.com/howto/howto_js_copy_clipboard.asp
You can also use this -
Just call myFunction with your returned text as an argument.
function myFunction(arg) {
var x = document.createElement("INPUT");
x.setAttribute("type", "text");
x.setAttribute("value",arg);
x.select();
document.execCommand("Copy");
alert("Copied the text: " + x.value);
document.removeChild(x);
}
document.execCommand("copy") this will copied all your selected text !
function copySelectionText(){
var copysuccess // var to check whether execCommand successfully executed
try{
copysuccess = document.execCommand("copy") // run command to copy selected text to clipboard
} catch(e){
copysuccess = false
}
return copysuccess
}
document.body.addEventListener('mouseup', function(e){
var copysuccess = copySelectionText() // copy user selected text to clipboard
if(copysuccess) {
document.getElementById('paste').style.display = "block";
}
}, false)
<h3>Late</h3>
<p>dsfjdslkfjdslkfjdsklfj</p>
<code>Cdoing is godo for a wite </code>
<textarea placeholder="Paste Here with [Ctrl + V ]" style="display:none;" id="paste"> </textarea>
Related
In my Web App I have have an TextEditor, which can be manipulated by some buttons.
For example:
<textarea id="textareaId"></textarea>
<button onclick="add()">Click me</button>
<script>
add() {
document.getElementById('textareaId').value += 'some content';
}
</script>
The issue is, that the user cant undo this (for example by shortcut ctrl + z).
It looks like that the the undo-buffor for the textarea gets cleared by that. Is there any way to do the changes without losing the option of undoing?
You can cache the textarea's value using an array as stack:
var valuesStack = [];
var textarea = document.getElementById('textareaId');
textarea.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.key === 'z') restore();
});
function cache() {
valuesStack.push(textarea.value);
}
function add() {
cache();
textarea.value += 'some content';
}
function restore() {
var value = valuesStack.pop();
if (value === undefined) textarea.value = "";
else textarea.value = value;
}
<textarea id="textareaId" onchange="cache()"></textarea>
<button onclick="add()">Click me</button>
There are quite a few posts on this but after spending several hours trying to adapt the solutions that already exist, it's become clear to me that this is a little bit more complicated.
I'm attempting to create 'copy to clipboard' functionality so that our users can copy their serial number with a single click (I managed to achieve this functionality with 2 different solutions) but there's a major catch.
As the serial number is generated dynamically using a shortcode I cannot place it inside a HTML 'text'/'value' field, like so:
<input id="serial" value="[shortcode here]">
as this breaks the shortcode, so it has to be placed inside it's own div, which I have done like this:
<div id="serial">[shortcode here]</div>
This outputs the shortcode on the page with the direct parent ID of 'serial', so the JS I'm using should then select the text from the element ID - #serial.
Unfortunately it doesn't...
I've tried to adapt this method also with no luck:
From the Roll Your Own section: https://www.sitepoint.com/javascript-copy-to-clipboard/
This one was working with with plain text but not with the shortcode or custom div.
Can anyone provide me with a working clipboard solution as shown in the example above that won't break the shortcode?
document.getElementById("copyButton").addEventListener("click", function() {
copyToClipboardMsg(document.getElementById("copyTarget"), "msg");
});
document.getElementById("copyButton2").addEventListener("click", function() {
copyToClipboardMsg(document.getElementById("copyTarget2"), "msg");
});
document.getElementById("pasteTarget").addEventListener("mousedown", function() {
this.value = "";
});
function copyToClipboardMsg(elem, msgElem) {
var succeed = copyToClipboard(elem);
var msg;
if (!succeed) {
msg = "Copy not supported or blocked. Press Ctrl+c to copy."
} else {
msg = "Text copied to the clipboard."
}
if (typeof msgElem === "string") {
msgElem = document.getElementById(msgElem);
}
msgElem.innerHTML = msg;
setTimeout(function() {
msgElem.innerHTML = "";
}, 2000);
}
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = elem.textContent;
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
<input id="copyTarget" value="Some initial text"> <button id="copyButton">Copy</button><br><br>
<span id="copyTarget2">Some Other Text</span> <button id="copyButton2">Copy</button><br><br>
<input id="pasteTarget"> Click in this Field and hit Ctrl+V to see what is on clipboard<br><br>
<span id="msg"></span><br>
Would you please try above snippet?
Second #pruvik7373 answer
I think [shortcode] may contain some code which can translate into anything else so instead of using textContent use innerHTML it will make sure to copy everything as it is.
document.getElementById("copyButton").addEventListener("click", function() {
copyToClipboardMsg(document.getElementById("copyTarget"), "msg");
});
document.getElementById("copyButton2").addEventListener("click", function() {
copyToClipboardMsg(document.getElementById("serial"), "msg");
});
document.getElementById("pasteTarget").addEventListener("mousedown", function() {
this.value = "";
});
function copyToClipboardMsg(elem, msgElem) {
var succeed = copyToClipboard(elem);
var msg;
if (!succeed) {
msg = "Copy not supported or blocked. Press Ctrl+c to copy."
} else {
msg = "Text copied to the clipboard."
}
if (typeof msgElem === "string") {
msgElem = document.getElementById(msgElem);
}
msgElem.innerHTML = msg;
setTimeout(function() {
msgElem.innerHTML = "";
}, 2000);
}
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = elem.innerHTML;
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
<input id="copyTarget" value="Some initial text"> <button id="copyButton">Copy</button><br><br>
<div id="serial"><div>[pw_map address="New York City"</div> enablescrollwheel="false" key="YOUR API KEY"]</div> <button id="copyButton2">Copy</button><br><br>
<input id="pasteTarget"> Click in this Field and hit Ctrl+V to see what is on clipboard<br><br>
<span id="msg"></span><br>
Below code did the trick for me.
Note: Below snippet might not work as window object is not accessible.
$(function() {
$('#serial').click(function() {
window.clipboardData.setData('text', $(this).text());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="serial">[shortcode here]</div>
You can do it like:
<div id="serial">[shortcode here]</div>
<input id="some_other_id" type="text" />
And the javascript code:
//first get text from your div and put it inside input field
//then apply code to copy that text from input field
$(document).ready(function(){
var text = $("#serial").text();
$("#some_other_id").val(text);
//your code for copying text from input field goes here
});
I'm trying to set a variation of this Javascript: How to detect if a word is highlighted , but I'd like to run the function getSelectedText only if the selected text matches the value of the h1 id
The code I set looks like:
function getSelectedText() {
var x = document.getElementById("titleProduct");
var text = "";
if (typeof window.getSelection === x) {
alert('hey');
text = window.getSelection().toString();
}
return text;
}
function doSomethingWithSelectedText() {
var selectedText = getSelectedText();
if (selectedText) {
document.getElementById("hiddenCTA").className = "visibleCTA";
}
}
var x = document.getElementById("titleProduct");
document.onmouseup = doSomethingWithSelectedText;
I included the alert('hey') inside that if loop to see that is running, just for testing but there is no evidence of it in my tests, nor I can see any errors in the console. The whole code is in http://codepen.io/malditojavi/pen/LWmRvp?editors=1010
In this case, the function should only run if the full string 'Title Of Your Product' is selected, not any other text within the HTML document.
Your if should be:
if (window.getSelection().toString() === x.textContent) {
But it seems your function could just return a boolean indicating if the expected text was matched. As you already know the text in that case, it suffices to return true or false. Here is how I would suggest writing it:
function isSelectedText(txt) {
return window.getSelection().toString().trim() === txt;
}
function doSomethingWhenTextSelected() {
if (isSelectedText(document.getElementById("titleProduct").textContent)) {
document.getElementById("hiddenCTA").className = "visibleCTA";
}
}
document.onmouseup = doSomethingWhenTextSelected;
.hiddenCTA { display: none }
.visibleCTA { display: block }
<h3 id="titleProduct">Title Of Your Product</h3>
hhhh
<div class="hiddenCTA" id="hiddenCTA">Hey, we do price match!</div>
I have a simple input:
<input type="date" class="self-select" value="1980-05-04">
<input type="text" class="self-select" value="my birthday">
And I have a listener for all such inputs:
$(document).on('focus', '.self-select', function(){
$(this).select();
});
The idea is that when user clicks to the input field, its' contents are selected, so he needs just ctrl+c to copy.
But this doesnt work with type="date" in Chrome. There is no selection and basically no way to copy date value from an input field.
Here is the fiddle:
https://fiddle.jshell.net/Dmatafonov/s8r9dt6j/
I managed to write some kind of a "hacky" walk around...
The trick is to copy to clipboard (using this other great SO answer) while the date input type is temporarely setted to "text" on CTRL+C keydown...
It's not perfect since only a segment of the date is selected on focus...
And some users will scratch their head a little until they notice that the whole date is copied anyway.
I have no solution for this.
What's important is that copying to clipboard is works.
Try the snippet!
// Your on focus -> select event handler
$(document).on('focus', '.self-select', function(){
$(this).select();
});
// An on keydown event handler to copy to clipboard when [ctrl]+[C] is pressed
// Exclusively for the "date" inputs.
$(document).on('keydown', 'input[type="date"]', function(e){
if( e.which == 67 && e.ctrlKey ){
var copiedDate = $(this).val();
//console.log( copiedDate );
// First, get the value and fix the date format from YYYY-MM-DD to MM/DD/YYYY
var tempDate = copiedDate.split("-");
var year = tempDate.shift();
//console.log( year );
tempDate.push(year);
var fixedDate = tempDate.join("/");
console.log( fixedDate );
// Then temporarly change the input type from "date" to "text"
$(this).attr("type","text").val(fixedDate);
// Use the copy to clipboard function
$(this).select();
copyToClipboard($(this));
// Set the input type back to "date" a small delay later
var that=$(this);
setTimeout(function(){
that.attr("type","date").val(copiedDate); // And restore original value
},20)
}
});
// ---------------------------------
// A nice JavaScript "copy to clipboard" function found here : https://stackoverflow.com/a/22581382/2159528
// ---------------------------------
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = elem.textContent;
}
// select the content
var currentFocus = document.activeElement;
//target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
/* Textarea sizing for this snippet */
#pasteIt{
width:316px;
height:150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="date" class="self-select" value="1980-05-04">
<input type="text" class="self-select" value="my birthday">
<br>
<br>
<textarea id="pasteIt" placeholder="Paste here to test your clipboard."></textarea>
I ran into this same issue but also needed to be able to paste to another date field. I did something similar to the above but made it obvious to the user that the full date is being copied.
My use case also included the need to copy from and paste to datetime-local type fields.
https://jsfiddle.net/h444uL45/23/
var control_pressed = false;
function changeInputType(oldObject, oType) {
var newObject = document.createElement("input");
newObject.type = oType;
if(oldObject.size) {newObject.size = oldObject.size;}
if(oldObject.value) {newObject.value = oldObject.value;}
if(oldObject.name) {newObject.name = oldObject.name;}
if(oldObject.id) {newObject.id = oldObject.id;}
if(oldObject.className) {newObject.className = oldObject.className;}
oldObject.parentNode.replaceChild(newObject,oldObject);
newObject.select();
return newObject;
}
function swapToText(date_type) {
$('input[type="'+date_type+'"]').on("keydown", function(event) {
if ((event.keyCode == 17) && (control_pressed != true)) {
$(this).addClass("revert_date_to_text");
changeInputType(this, "text");
swapToDate(date_type);
control_pressed = true;
}
})
}
function swapToDate(date_type) {
$(".revert_date_to_text").on("keyup", function(event) {
if ((event.keyCode == 17) && (control_pressed != false)) {
$(this).removeClass("revert_date_to_text");
if (date_type == 'datetime-local') {
$(this).val($.format.date($(this).val().replace(/\//g,"-").replace("T"," ")+':00.000', "yyyy-MM-ddTHH:mm"));
} else {
$(this).val($.format.date($(this).val().replace(/\//g,"-"), "yyyy-MM-dd"));
}
changeInputType(this, date_type);
swapToText(date_type);
control_pressed = false;
}
})
}
$(function() {
$.getScript('https://cdnjs.cloudflare.com/ajax/libs/jquery-dateFormat/1.0/jquery.dateFormat.min.js');
swapToText('date');
swapToText('datetime-local');
});
I want to create "copy to clipboard" buttons to work on our sharepoint. They should be placed in a few different places, and what I need to copy is some text from from a specific field on the page (ex. a list of emails).
I know, I can just select the text and copy it, but we do it quite often, so having a button that automatically copies the text to the clipboard would be very useful.
I did manage to create one in a Script Editor, where I pasted the whole code below (which I found on the internet)
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>//<![CDATA[
window.onload=function(){
document.getElementById("copyButton").addEventListener("click", function() {
copyToClipboardMsg(document.getElementById("copyTarget"), "msg");
});
document.getElementById("copyButton2").addEventListener("click", function() {
copyToClipboardMsg(document.getElementById("copyTarget2"), "msg");
});
document.getElementById("pasteTarget").addEventListener("mousedown", function() {
this.value = "";
});
function copyToClipboardMsg(elem, msgElem) {
var succeed = copyToClipboard(elem);
var msg;
if (!succeed) {
msg = "Copy not supported or blocked. Press Ctrl+c to copy."
} else {
msg = "Text copied to the clipboard."
}
if (typeof msgElem === "string") {
msgElem = document.getElementById(msgElem);
}
msgElem.innerHTML = msg;
setTimeout(function() {
msgElem.innerHTML = "";
}, 2000);
}
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);
}
target.textContent = elem.textContent;
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
return succeed;
}
}//]]>
</script>
</head>
<body>
<input id="copyTarget" value="Some initial text"> <button id="copyButton">Copy</button><br><br>
<span id="copyTarget2">Some Other Text</span> <button id="copyButton2">Copy</button><br><br>
<input id="pasteTarget"> Click in this Field and hit Ctrl+V to see what is on clipboard<br><br>
<span id="msg"></span><br>
</body>
</html>
But we have main problems with it:
1) it reloads the page every time we click the "copy" button
2) it is not very elegant and friendly, when we think about updating our documents
I would be very grateful for any hints you may have for me, on how to make it work better.
This project may help: clipboardjs