i have a button outside ckeditor, when clicked i want to insert a span element at caret position, this is what i have so far:
var el = document.querySelector('#editor');
ClassicEditor.create(el, {
licenseKey: ''
}).then( editor => {
appConfigs.editor = editor; //storing the editor for later usage
}).catch( error => {
//...
});
when the button is clicked i do:
function clickHandler(){
var editor = appConfigs.editor;
editor.model.change( writer => {
var html = '<span class="special-class-name" data-name="something">special word or button</span>';
var viewFragment = editor.data.processor.toView(html);
var modelFragment = editor.data.toModel(viewFragment);
var insertPosition = editor.model.document.selection.getFirstPosition();
editor.model.insertContent(modelFragment, insertPosition);
});
}
the code have the following issues:
1)the inserted span get stripped off all its attributes(class, data-name) which i want to preserve.
2)the editing caret doesn't go back automatically to the editor when the button clicked.
3)when i click the editor to restore caret and start typing, i noticed it edits the text inside inserted span, i want inserted span to be untouched and any further typing goes after it.
i will be so grateful if anyone could help me with those issues.
I am trying to create a copy image functionality using the following code:
// Code goes here
function CopyImageById(Id)
{
const imgs = document.createElement('img');
imgs.src = document.getElementById(Id).src;
//alert ('Create image') ;
const bodys = document.body ;
bodys.appendChild(imgs);
//alert ('Image on document')
let myrange;
if (document.createRange)
{
//alert ('CreateRange work');
myrange = document.createRange();
myrange.setStartBefore(imgs);
myrange.setEndAfter(imgs);
myrange.selectNode(imgs);
}
else
{
alert ('CreateRange not working');
}
const sel = window.getSelection();
sel.addRange(myrange);
const successful = document.execCommand('copy');
const msg = successful ? 'successful' : 'unsuccessful';
//alert('Copy image command was ' + msg);
bodys.removeChild(imgs);
document.getElementById('answer').innerHTML="Copy image command was " + msg ;
}
Reproducer: http://jsfiddle.net/xz14jp3f/
The copied image however is only pasting on word document such as google doc, but not on all the places such slack or stackoverflow. If you copy the image using the chrome's right click context menu option to copy the image, we can paste it everywhere.
How can I fix this?
I started using clipboards.js to copy the content of a div with the click of the button but now I need to save it to a string so I can delete new lines to be shown like 1 paragraph but I cannot access to data that is stored to clipboard
this function here is to save to clipboard using clipboard.js and you can see I was trying to save it to "var str2" but it shows this "Cannot read property '_target' of undefined"
_this.testClick = function () {
var clipboard = new Clipboard('.clipboard');
var str2 = clipboard.clipboardAction._target.innerText.replace(/\n|\r/g, "");
_this.copyStringToClipboard(str2);
};
and this is the function that copies again but without spaces
_this.copyStringToClipboard = function (str) {
// Create new element
var el = document.createElement('textarea');
// Set value (string to be copied)
el.value = str;
// Set non-editable to avoid focus and move outside of view
el.setAttribute('readonly', '');
el.style = {
position: 'absolute',
left: '-9999px'
};
document.body.appendChild(el);
// Select text inside element
el.select();
// Copy text to clipboard
document.execCommand('copy');
// Remove temporary element
document.body.removeChild(el);
}
how can I access to inner text or clipboard so I can save it to str2?
Try using ClipboardJS() and success event
var clipboard = new ClipboardJS('.clipboard');
clipboard.on('success', function(e) {
console.log(e.text);
console.log(e.text.replace(/\n|\r/g, ""));
});
<script src="https://cdn.jsdelivr.net/npm/clipboard#2/dist/clipboard.min.js"></script>
<button class="clipboard" data-clipboard-text="Just
because
you can
doesn't mean you should — clipboard.js">
Copy
</button>
Not sure why this has been so difficult for me today, but for some reason I cannot seem to get it to copy the current URL to the clipboard. Overall, I'm looking for a way to do it without needing to create some hidden text elements.
This is what I'm trying so far:
var shareBtn = document.querySelector(".share-button");
shareBtn.addEventListener('click', function(event) {
var cpLink = window.location.href;
cpLink.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
console.log('Copy command was ' + msg);
} catch (err) {
console.log('Oops, unable to copy');
}
event.preventDefault;
});
When I try to go about it using the .select() I get this error:
t.select is not a function
So I'm not 100% sure what the best way to go about this. Again, without using jQuery (or any other JS library) and not using some sort of hidden textfield.
You can create a temporary DOM element to hold the URL
Unfortunately there is no standard API for clipboard operations, so we're left with the hacky way of using a HTML input element to fit our needs. The idea is to create an input, set its value to the URL of the current document, select its contents and execute copy.
We then clean up the mess instead of setting input to hidden and polluting the DOM.
var dummy = document.createElement('input'),
text = window.location.href;
document.body.appendChild(dummy);
dummy.value = text;
dummy.select();
document.execCommand('copy');
document.body.removeChild(dummy);
2021 update: you can use the Clipboard API like so:
navigator.clipboard.writeText(window.location.href);
ppajer's answer is indeed all that's needed when the browser handles the copying, without any custom handling of clipboard events being involved.
But if you or some library hook into the copy event (say, window.addEventListener('copy', ...) and then if that handler relies on using window.getSelection(), then a 19 year old Firefox issue will bite you. Like MDN says:
It is worth noting that currently getSelection() doesn't work on the content of <textarea> and <input> elements in Firefox, Edge (Legacy) and Internet Explorer.
So, getSelection() returns a non-null result after HTMLInputElement#select, but without providing the actual selected content. Easily fixed by using a non-input element to temporarily hold the URL:
function copyUrl() {
if (!window.getSelection) {
alert('Please copy the URL from the location bar.');
return;
}
const dummy = document.createElement('p');
dummy.textContent = window.location.href;
document.body.appendChild(dummy);
const range = document.createRange();
range.setStartBefore(dummy);
range.setEndAfter(dummy);
const selection = window.getSelection();
// First clear, in case the user already selected some other text
selection.removeAllRanges();
selection.addRange(range);
document.execCommand('copy');
document.body.removeChild(dummy);
}
(The above will also work when no custom handler hooks into the copy event.)
this might be one of the simpler ways to do it
window.navigator.clipboard.writeText(textToCopy);
var $temp = $("<input>");
var $url = $('.copy').attr('href');
$('.clipboard').on('click', function() {
$("body").append($temp);
$temp.val($url).select();
document.execCommand("copy");
$temp.remove();
const Toast = Swal.mixin({
toast: true,
position: 'top-end',
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.addEventListener('mouseenter', Swal.stopTimer)
toast.addEventListener('mouseleave', Swal.resumeTimer)
}
})
Toast.fire({
icon: 'success',
title: 'URL copied! '
})
})
I have no knowledge of JavaScript, but I managed to put this code together using bits and bolts from various Stack Overflow answers. It works OK, and it outputs an array of all selected checkboxes in a document via an alert box.
function getSelectedCheckboxes(chkboxName) {
var checkbx = [];
var chkboxes = document.getElementsByName(chkboxName);
var nr_chkboxes = chkboxes.length;
for(var i=0; i<nr_chkboxes; i++) {
if(chkboxes[i].type == 'checkbox' && chkboxes[i].checked == true) checkbx.push(chkboxes[i].value);
}
return checkbx;
}
And to call it I use:
<button id="btn_test" type="button" >Check</button>
<script>
document.getElementById('btn_test').onclick = function() {
var checkedBoxes = getSelectedCheckboxes("my_id");
alert(checkedBoxes);
}
</script>
Now I would like to modify it so when I click the btn_test button the output array checkbx is copied to the clipboard. I tried adding:
checkbx = document.execCommand("copy");
or
checkbx.execCommand("copy");
at the end of the function and then calling it like:
<button id="btn_test" type="button" onclick="getSelectedCheckboxes('my_id')">Check</button>
But it does not work. No data is copied to clipboard.
function copyToClipboard(text) {
var dummy = document.createElement("textarea");
// to avoid breaking orgain page when copying more words
// cant copy when adding below this code
// dummy.style.display = 'none'
document.body.appendChild(dummy);
//Be careful if you use texarea. setAttribute('value', value), which works with "input" does not work with "textarea". – Eduard
dummy.value = text;
dummy.select();
document.execCommand("copy");
document.body.removeChild(dummy);
}
copyToClipboard('hello world')
copyToClipboard('hello\nworld')
OK, I found some time and followed the suggestion by Teemu and I was able to get exactly what I wanted.
So here is the final code for anyone that might be interested. For clarification, this code gets all checked checkboxes of a certain ID, outputs them in an array, named here checkbx, and then copies their unique name to the clipboard.
JavaScript function:
function getSelectedCheckboxes(chkboxName) {
var checkbx = [];
var chkboxes = document.getElementsByName(chkboxName);
var nr_chkboxes = chkboxes.length;
for(var i=0; i<nr_chkboxes; i++) {
if(chkboxes[i].type == 'checkbox' && chkboxes[i].checked == true) checkbx.push(chkboxes[i].value);
}
checkbx.toString();
// Create a dummy input to copy the string array inside it
var dummy = document.createElement("input");
// Add it to the document
document.body.appendChild(dummy);
// Set its ID
dummy.setAttribute("id", "dummy_id");
// Output the array into it
document.getElementById("dummy_id").value=checkbx;
// Select it
dummy.select();
// Copy its contents
document.execCommand("copy");
// Remove it as its not needed anymore
document.body.removeChild(dummy);
}
And its HTML call:
<button id="btn_test" type="button" onclick="getSelectedCheckboxes('ID_of_chkbxs_selected')">Copy</button>
For general purposes of copying any text to the clipboard, I wrote the following function:
function textToClipboard (text) {
var dummy = document.createElement("textarea");
document.body.appendChild(dummy);
dummy.value = text;
dummy.select();
document.execCommand("copy");
document.body.removeChild(dummy);
}
The value of the parameter is inserted into value of a newly created <textarea>, which is then selected, its value is copied to the clipboard and then it gets removed from the document.
Very useful. I modified it to copy a JavaScript variable value to clipboard:
function copyToClipboard(val){
var dummy = document.createElement("input");
dummy.style.display = 'none';
document.body.appendChild(dummy);
dummy.setAttribute("id", "dummy_id");
document.getElementById("dummy_id").value=val;
dummy.select();
document.execCommand("copy");
document.body.removeChild(dummy);
}
When you need to copy a variable to the clipboard in the Chrome dev console, you can simply use the copy() command.
https://developers.google.com/web/tools/chrome-devtools/console/command-line-reference#copyobject
I managed to copy text to the clipboard (without showing any text boxes) by adding a hidden input element to body, i.e.:
function copy(txt){
var cb = document.getElementById("cb");
cb.value = txt;
cb.style.display='block';
cb.select();
document.execCommand('copy');
cb.style.display='none';
}
<button onclick="copy('Hello Clipboard!')"> copy </button>
<input id="cb" type="text" hidden>
Use Clipboard API
text = "HEllo World";
navigator.clipboard.writeText(text)
It works on Chrome 66+, Edge 79+, Firefox 63+ & doesn't work on I.E.
Read More About Clipboard API At MDN Docs
Nowadays there is a new(ish) API to do this directly. It works on modern browsers and on HTTPS (and localhost) only. Not supported by IE11.
IE11 has its own API.
And the workaround in the accepted answer can be used for unsecure hosts.
function copyToClipboard (text) {
if (navigator.clipboard) { // default: modern asynchronous API
return navigator.clipboard.writeText(text);
} else if (window.clipboardData && window.clipboardData.setData) { // for IE11
window.clipboardData.setData('Text', text);
return Promise.resolve();
} else {
// workaround: create dummy input
const input = h('input', { type: 'text' });
input.value = text;
document.body.append(input);
input.focus();
input.select();
document.execCommand('copy');
input.remove();
return Promise.resolve();
}
}
Note: it uses Hyperscript to create the input element (but should be easy to adapt)
There is no need to make the input invisible, as it is added and removed so fast. Also when hidden (even using some clever method) some browsers will detect it and prevent the copy operation.
At the time of writing, setting display:none on the element didn't work for me. Setting the element's width and height to 0 did not work either. So the element has to be at least 1px in width for this to work.
The following example worked in Chrome and Firefox:
const str = 'Copy me';
const el = document.createElement("input");
// Does not work:
// dummy.style.display = "none";
el.style.height = '0px';
// Does not work:
// el.style.width = '0px';
el.style.width = '1px';
document.body.appendChild(el);
el.value = str;
el.select();
document.execCommand("copy");
document.body.removeChild(el);
I'd like to add that I can see why the browsers are trying to prevent this hackish approach. It's better to openly show the content you are going copy into the user's browser. But sometimes there are design requirements, we can't change.
I just want to add, if someone wants to copy two different inputs to clipboard. I also used the technique of putting it to a variable then put the text of the variable from the two inputs into a text area.
Note: the code below is from a user asking how to copy multiple user inputs into clipboard. I just fixed it to work correctly. So expect some old style like the use of var instead of let or const. I also recommend to use addEventListener for the button.
function doCopy() {
try{
var unique = document.querySelectorAll('.unique');
var msg ="";
unique.forEach(function (unique) {
msg+=unique.value;
});
var temp =document.createElement("textarea");
var tempMsg = document.createTextNode(msg);
temp.appendChild(tempMsg);
document.body.appendChild(temp);
temp.select();
document.execCommand("copy");
document.body.removeChild(temp);
console.log("Success!")
}
catch(err) {
console.log("There was an error copying");
}
}
<input type="text" class="unique" size="9" value="SESA / D-ID:" readonly/>
<input type="text" class="unique" size="18" value="">
<button id="copybtn" onclick="doCopy()"> Copy to clipboard </button>
function CopyText(toCopy, message) {
var body = $(window.document.body);
var textarea = $('<textarea/>');
textarea.css({
position: 'fixed',
opacity: '0'
});
textarea.val(toCopy);
body.append(textarea);
textarea[0].select();
try {
var successful = document.execCommand('copy');
if (!successful)
throw successful;
else
alert(message);
} catch (err) {
window.prompt("Copy to clipboard: Ctrl+C, Enter", toCopy);
}
textarea.remove();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<button type="button" onClick="CopyText('Hello World', 'Text copped!!')">Copy</button>