Cant Copy Text To Clipboard - javascript

I am using hadlerbars as the view engine for express and i want the text in the variable code to be copied to the clipboard i tried many solutions . This is my current code
function copyLink() {
var copytext = document.getElementById('alcslink').innerHTML
let code = copytext.split(":- ").pop() /*formatted */
code.select();
code.setSelectionRange(0, 99999); /* For mobile devices */
/* Copy the text inside the text field */
navigator.clipboard.writeText(code.value);
}
when i run this it gives me this error in the web console
TypeError: code.select is not a function

This is how I use it:
Note, it does not work in the snippet engine. You will need to add it to your code.
Sorry.
const writeToClipboard = async (txt) => {
const result = await navigator.permissions.query({ name: "clipboard-write" });
if (result.state == "granted" || result.state == "prompt") {
await navigator.clipboard.writeText(txt);
console.log('Copied to clipboard');
}
};
document.querySelector('button').addEventListener('click', async () => {
const el = document.querySelector('div');
await writeToClipboard(el.innerHTML);
});
<div>copy me</div>
<button>Click</button>

Related

Why copy to clipboard doesn't work using JavaScript?

I'm trying this function:
function copyToClipboard(str) {
const el = document.createElement('textarea');
el.textContent = str;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
const selected =
document.getSelection().rangeCount > 0 ?
document.getSelection().getRangeAt(0) :
false;
el.select();
document.execCommand('copy');
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
alert("Success");}
I've tried with el.value = str; too.
What am I doing wrong?
The document.execCommand has been deprecated but still accessible across web browsers
The navigator.clipboard API is an alternative navigator.clipboard
You pass in the text to be copied to the clipboard like so
navigator.clipboard.writeText(str_to_copy).then(success_callback, failure_callback);
Note that the tab must be active for this to work else you won’t have permissions to copy the clipboard
The API is asynchronous so you can use the .then callback to alert the user if copying the clipboard was successful or not. Check out the Can I Use for its availability across web browsers.
You are creating an element that will be appended to DOM for a split second, just to allow the execCommand("copy")... And that will "display" at left -9999px.
So why the el.setAttribute('readonly', ''); ?
Just remove it and try again. My guess is the el.select(); just doesn't work on a readonly element.
Disclaimer: I did test nothing. But from what I read, this is the only weird thing to mention. Else is to find a duplicate answer or mark it as unreproducible.
Use this way to copy the text to clipboard.
function copyToClipboradFunc() {
let copiedText = document.getElementById("copyMe");
copiedText.select();
copiedText.setSelectionRange(0, 99999);
document.execCommand("copy");
console.log("Copied the text: " + copiedText.value);
}
<input type="text" value="Amoos Check Console" id="copyMe">
<button onclick="copyToClipboradFunc()">Copy to Clipboard</button>
Minor edits in your code.
/*
YOUR CODE
*/
function copyToClipboard(str) {
const el = document.createElement('textarea');
el.textContent = str;
el.setAttribute('readonly', '');
el.style.position = 'absolute';
el.style.left = '-9999px';
document.body.appendChild(el);
const selected =
document.getSelection().rangeCount > 0 ?
document.getSelection().getRangeAt(0) :
false;
el.select();
document.execCommand('copy');
document.body.removeChild(el);
if (selected) {
document.getSelection().removeAllRanges();
document.getSelection().addRange(selected);
}
alert("Copy Text: " + str );}
<!-- YOUR CODE -->
<button onclick="copyToClipboard('Your Function Copied')">Copy ( Original Function )</button>
Well, after some research I found the solution. Thanks to #VLAZ and #a.mola I found out that execCommand is deprecated. So I started to look for alternatives. I found about the clipboard API on this page Using the Clipboard API, that's from https://developer.mozilla.org/, so we know that's serious business. Anyway, here's my working function:
function copyToClipboard(str) {
navigator.permissions.query({
name: "clipboard-write"
}).then(result => {
if (result.state == "granted") {
navigator.clipboard.writeText(str).then(function () {
alert("Enlace copiado con succeso!");
}, function () {
alert("No fue posible copiar el enlace.");
});
}
});
};
I am using this. navigator.clipboard doesnt work for http.
function CopyToClipBoard(textToCopy) {
var successMessage = 'Success! The text was copied to your clipboard';
var errorMessage = 'Oops! Copy to clipboard failed. ';
// navigator clipboard api needs a secure context (https)
if (navigator.clipboard && window.isSecureContext) {
// navigator clipboard api method'
navigator.clipboard.writeText(textToCopy).then(
function () {
/* clipboard successfully set */
console.log(successMessage)
},
function () {
/* clipboard write failed */
console.warn(errorMessage)
}
)
} else
if (document.queryCommandSupported && document.queryCommandSupported("copy")) {
// text area method
var textarea = document.createElement("textarea");
textarea.value = textarea.textContent = textToCopy;
textarea.style.opacity = "0";
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
var selection = document.getSelection();
var range = document.createRange();
range.selectNode(textarea);
selection.removeAllRanges();
selection.addRange(range);
try {
var successful = document.execCommand('copy'); // Security exception may be thrown by some browsers.
var msg = successful ? console.log(successMessage) : console.warn(errorMessage);
}
catch (ex) {
console.warn(errorMessage, ex);
}
finally {
selection.removeAllRanges();
document.body.removeChild(textarea);
}
}

Copy default value to clipboard

I want to copy a default value to clipboard, without using input. Thats something wrong with my function, but I don't know what it is.
var copyText = "Default value";
const showText = document.querySelector(".copied");
const copyMeOnClipboard = () => {
copyText;
document.execCommand("copy")
showText.innerHTML = `Copied!`
setTimeout(() => {
showText.innerHTML = ""
}, 1000)
}
<button class="submitBtn" onclick="copyMeOnClipboard();">Copy link</button>
<p class="copied"></p>
From MDN's page on execCommand, emphasis added:
Copies the current selection to the clipboard. Conditions of having this behavior enabled vary from one browser to another, and have evolved over time.
You'll want to use the Clipboard API's writeText instead, like so:
var copyText = "Default value";
const showText = document.querySelector(".copied");
const copyMeOnClipboard = () => {
navigator.clipboard.writeText(copyText).then(() => {
showText.innerHTML = `Copied!`
setTimeout(() => {
showText.innerHTML = ""
}, 1000)
})
}
<button class="submitBtn" onclick="copyMeOnClipboard();">Copy</button>
<p class="copied"></p>

PowerPoint Javascript API getting slides property of presentation

I have tried many ways to do this, but I can not just get PowerPoint.SlideCollection, or PowerPoint.Slide with any code that I tried. There are no examples about this on the documentation. What code snippet can I write inside PowerPoint.run() to get PowerPoint.SlideCollection(slides) or a particular slide PowerPoint.Slide?
Here is the code I wrote:
function log(str) { document.getElementById('log').textContent += '\n[LOG]' + str; }
function logObject(obj) { log(JSON.stringify(obj)); }
Office.onReady(info => {
if(info.host === Office.HostType.PowerPoint) {
OfficeExtension.config.extendedErrorLogging = true;
document.getElementById("sideload-msg").style.display = "none";
document.getElementById("app-body").style.display = "flex";
document.getElementById("run").onclick = getSlideCollection;
}
});
async function getSlideCollection() {
await PowerPoint.run(async function(context) {
let slides = context.presentation.slides;
await context.sync().then((res)=>{
logObject(res);
}).catch((err)=>{
logObject(err);
});
});
}
The error I am getting:
{"name":"RichApi.Error","code":"GeneralException","traceMessages":[],"innerError":null,"debugInfo":{"code":"GeneralException","message":"GeneralException","errorLocation":"Presentation.slides","statement":"var slides = root.slides;","surroundingStatements":["var root = context.root;","// >>>>>","var slides = root.slides;","// <<<<<"],"fullStatements":["var root = context.root;","var slides = root.slides;"]},"httpStatusCode":500}
Here's a simple code snippet could help you:
function GetSlideCollection() {
await PowerPoint.run(async function(context) {
let slides = context.presentation.slides;
await context.sync();
});
}
You should import preview API js file (You can refer this document) as .slides is a beta feature (in preview).

Is there a way to subscribe to changes in window.getSelection?

We are able to get a selection range via window.getSelection().
I'm wondering whether there is a way to subscribe to window.getSelection changes.
The only way which came to me is to use timeouts (which is obviously bad) or subscribe to each user's key \ mouse press event and track changes manually.
ANSWER UPD: You are able to use this library, I've published it, as there are no more suitable ones: https://github.com/xnimorz/selection-range-enhancer
Use the onselect event.
function logSelection(event) {
const log = document.getElementById('log');
const selection = event.target.value.substring(event.target.selectionStart, event.target.selectionEnd);
log.textContent = `You selected: ${selection}`;
}
const textarea = document.querySelector('textarea');
textarea.onselect = logSelection;
<textarea>Try selecting some text in this element.</textarea>
<p id="log"></p>
For specific cases such as span contenteditable, you can make a polyfill:
function logSelection() {
const log = document.getElementById('log');
const selection = window.getSelection();
log.textContent = `You selected: ${selection}`;
}
const span = document.querySelector('span');
var down = false;
span.onmousedown = () => { down = true };
span.onmouseup = () => { down = false };
span.onmousemove = () => {
if (down == true) {
logSelection();
}
};
<span contenteditable="true">Try selecting some text in this element.</span>
<p id="log"></p>
if Im undesrting in right way you want to know when user start selection on page you can use DOM onselectstart.
document.onselectstart = function() {
console.log("Selection started!");
};
more info MDN

Why doesn't my input onChange work in Edge?

No error messages, the file gets selected, however the input.onchange = () => {} never gets called.
I added: to the top of HTML to no result. Any idea why this doesn't work in Edge?
toolbar.addHandler('image', () => {   
const range = this.quillReply.getSelection();
this.selectLocalImage()
})
toolbar.addHandler('link', (value) => {
if (value) {
var href = prompt('Enter the URL');
this.quillReply.format('link', href);
} else {
this.quillReply.format('link', false);
}
});
}
selectLocalImage = () => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.click();
// Listen upload local image and save to server
input.onchange = () => {
}
}
The C should be capitalized in onChange.
I also met this question,this code snippets seems to be used in quill editor as a image uploader plugin.
I solved it after change the "selectLocalImage" function to below:
/**
* Select local image
*/
selectLocalImage = () => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.addEventListener('change', () => {
// do something like upload local image and save to server
});
input.click();
}
tested in edge 44 and chrome 71.

Categories