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>
Related
Hi I just wondering if i can get some pointers with my code, I am trying to capture and save the input value of a textarea. I am fairly new to JavaScript and I have been wrecking my brain trying to figure it out. My issue is regarding the saveEntry() function, which isn't complete I have only posted how my code is right now, and isn't causing errors/unwanted effects. Any tips or hints would be fantastic, as I keep getting errors
function addTextEntry(key, text, isNewEntry) {
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById('textarea').value;
// ...make a text item using the value
// ...store the item in local storage using the given key
localstroage.setItem(key, item);
}
// Connect the saveEntry event listener to the textarea element 'change' event
textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
I was told to utilise something similar to this code below, but not exactly the same as I need to capture the data value of the user input text, not pre-created data.
function createDemoItems() {
console.log("Adding demonstration items to local storage");
var item, data, key;
// Make a demo text item
data =
"Friday: We arrived to this wonderful guesthouse after a pleasant journey " +
"and were made most welcome by the proprietor, Mike. Looking forward to " +
"exploring the area tomorrow.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000001";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Saturday: After a super breakfast, we took advantage of one of the many " +
"signed walks nearby. For some of the journey this followed the path of a " +
"stream to a charming village.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000002";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo image item
data = window.DUMMY_DATA_URL;
item = makeItem("image", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000003";
// Store the item in local storage
localStorage.setItem(key, item);
// Make a demo text item
data =
"Sunday: Following a tip from Mike we drove to a gastropub at the head of " +
"the valley - a great meal and fabulous views all round.";
item = makeItem("text", data);
// Make a key using a fixed timestamp
key = "diary" + "1536771000004";
// Store the item in local storage
localStorage.setItem(key, item);
}
You are very close, you just have to make some adjustments here and there!
Just as a disclaimer, I had to re-create your addSection() function, in order to have it properly working. If you already had one, you could discard mine
When we create a new entry, in order to make it distinguishable, I have assigned it the id of the key. Before, you were trying to call getElemenyById("textarea"), but no element had id textarea, which is in fact the tag name of the textarea element that you created. Read more about getElementByTagName if you want.
I have changed the way the event listener is set to:
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
The difference between change and input are that change will fire only when you are done with the changes and click outside of the textarea, whilst input will fire everytime that you input something. Now you know, so of course, feel free to change it to what you would like it to behave.
Lastly, I have made the just-created item to be retrieved immediately and logged to console. This will be useful just for testing, you can comment out those lines when you are happy.
Beware that the snippet below is playable, but it won't actually save data to LocalStorage because of SO limitations, so you won't be able to fully test it on this page.
function addSection(key, element) {
element.id = key;
var test = document.querySelector("#test");
test.appendChild(element);
}
function addTextEntry(key, text, isNewEntry) {
// Create an event listener to save the entry when it changes
// (i.e. when the user types into the textarea)
function saveEntry() {
// Save the text entry:
// ...get the textarea element's current value
var currentValue = document.getElementById(key).value;
// ...store the item in local storage using the given key
localStorage.setItem(key, currentValue);
//Testing if we can retrieve the item, comment out when you're happy
var item = localStorage.getItem(key);
console.log(item);
}
// Create a textarea element to edit the entry
var textareaElement = document.createElement("textarea");
textareaElement.rows = 5;
textareaElement.placeholder = "(new entry)";
// Set the textarea's value to the given text (if any)
textareaElement.value = text;
// Add a section to the page containing the textarea
addSection(key, textareaElement);
// If this is a new entry (added by the user clicking a button)
// move the focus to the textarea to encourage typing
if (isNewEntry) {
textareaElement.focus();
}
textareaElement.addEventListener(
'input',
function () { saveEntry(); },
false
);
// Connect the saveEntry event listener to the textarea element 'change' event
//textareaElement.addEventListener("change", saveEntry());
}
function addImageEntry(key, url) {
// Create a image element
var imgElement = new Image();
imgElement.alt = "Photo entry";
// Load the image
imgElement.src = url;
// Add a section to the page containing the image
addSection(key, imgElement);
}
/**
* Function to handle Add text button 'click' event
*/
function addEntryClick() {
// Add an empty text entry, using the current timestamp to make a key
var key = "diary" + Date.now();
var text = "";
var isNewEntry = true;
addTextEntry(key, text, isNewEntry);
}
window.onload = () => addEntryClick();
<html>
<head>
</head>
<body>
<div id="test"></div>
</body>
</html>
There are a number of things wrong with the way you're doing things, but you know that: that's why you're here!
You have a typo: localstroage should be localStorage
You create a text area but don't give it an ID. In your saveData function you attempt to find it, but you're searching for it by tag name. There's no need to search: your event handler will already have this set to the element.
In your event handler you refer to your function as saveData(). This will invoke the function immediately and assign its return value as an event handler. Just pass the function name.
Here's a demonstration of concept for you:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Explore local storage</title>
</head>
<body>
<textarea id="txt" placeholder="Enter text and press TAB"></textarea>
<script>
"use strict";
let txtKey = "someKey"
// Save the data. No need to search for the text area:
// the special value 'this' is already set to it.
function saveEntry() {
localStorage.setItem(txtKey, this.value);
}
// Look fr the previous text and if it exists, put it in the textarea
let storedText = localStorage.getItem(txtKey);
if (storedText) {
document.getElementById('txt').value = storedText;
}
// Now add the event listener.
tArea.addEventListener('change', saveEntry); // Pass just the function name
</script>
</body>
</html>
This code uses a hard-coded value for txtKey. Your code might need to generate and track some value for the key, otherwise you risk overwriting earlier data with later data.
I am trying to copy some text to a clipboard upon clicking a button. Currently, its working when I have a separate function to copy different sections of the HTML that I want to copy, however when I write 1 function for both with a parameter it doesn't work.
I have 2 functions which look like this
function copyStringToClipboardA () {
// Create new element
var el = document.createElement('input');
// Set value (string to be copied)
el.value = document.getElementById("trackEvent").value;
// 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);
}
function copyStringToClipboardB() {
// Create new element
var el = document.createElement('input');
// Set value (string to be copied)
el.value = document.getElementById("identifyEvent").value;
// 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);
}
The only thing that is different in those 2 functions is el.value
I call these 2 functions on a button click which looks like this:
document.addEventListener("DOMContentLoaded", function(event){
//Event Examples
var b = document.getElementById('trackCopy');
var c = document.getElementById('identifyCopy');
b.addEventListener('click', copyStringToClipboardA, false);
c.addEventListener('click', copyStringToClipboardB, false)
});
I am trying to write 1 function that takes a string as a parameter instead of writing 2 functions.
I tried writing the following function which takes a string as a parameter:
function copyStringToClipboard(myInput) {
// Create new element
var el = document.createElement('input');
// Set value (string to be copied)
el.value = document.getElementById(myInput).value;
// 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);
}
and then I call it on click like this:
document.addEventListener("DOMContentLoaded", function(event){
//Event Examples
var b = document.getElementById('trackCopy');
var c = document.getElementById('identifyCopy');
b.addEventListener('click', copyStringToClipboard("trackEvent"), false);
c.addEventListener('click', copyStringToClipboard("identifyEvent"), false)
});
The issue I have with this implementation is that the second one identifyEvent is copied every time.
The behavior I want to achieve is copying the selected text into the clipboard.
I'm trying to replace the text in a TextArea with the contents of a string variable in a google chrome extension. But for some reason nothing changes in my result. Here's my code:
Content Script (js)
(function () {
// Holds text being selected in browser
var lwsSelectedText = '';
// Adds pop-up to current webpage
function lwsAddContent(callback) {
// Get body tag
var body = document.getElementsByTagName('body');
// add invisible div
document.body.innerHTML += '<div id="myModal" class="modal"><div class="modal-content"><span class="close">×</span><div id="lwsSpanishDiv"><p id="lwsSpanishTitle">Spanish</p><textarea id="lwsSpanishTextArea">Hello</textarea></div><div id="lwsEnglishDiv"><p id="lwsEnglishTitle">English</p><textarea id="lwsEnglishTextArea">Hello 2</textarea></div></div></div>';
callback(lwsSetUpTextGetter);
}
// Make the pop-up visible and set up close button
function lwsActivateContent(callback) {
var modal = document.getElementById('myModal');
// Get the textarea
var txtarea = document.getElementById("myTxtArea");
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
span.onclick = function () {
modal.style.display = "none";
}
callback();
}
// Initialize ability to select and grab text from browser
function lwsSetUpTextGetter(callback) {
//Set the onmouseup function to lwsGetText
document.onmouseup = lwsGetText;
//Handling clicking outside webpage?
if (!document.all) document.captureEvents(Event.MOUSEUP);
}
//Gets selected text
function lwsGetText(e) {
// Get access to spanish text area
var spanishText = document.getElementById('lwsSpanishTextArea');
//Get text
lwsSelectedText = (document.all) ? document.selection.createRange().text : document.getSelection();
//if nothing is selected, do nothing
if (lwsSelectedText != '') {
// test: does browser grab text correctly?
alert(lwsSelectedText);
// Set spanish text area content to the selected text from browser
// --Error here: does not set text at all--
spanishText.innerHTML(lwsSelectedText);
}
}
// When document ready
$(document).ready(function () {
lwsAddContent(lwsActivateContent);
});
})();
When I use the extension, the pop-up loads, and when I highlight some text, lwsSelectedText populates with the correct text and it displays in the alert but it doesn't display in my text area. Am I accessing the contents of lwsSpanishTextArea wrong?
Thanks!
To set the value in an input, you can use the property value instead of innerHTML.
var lwsSelectedText = "Hello world!";
var spanishText = document.getElementById("spanishText");
spanishText.value = lwsSelectedText;
<textarea id="spanishText"></textarea>
How can I copy a specific text with protractor ?
I would like to load a text to paste after with this command :
return browser.actions().sendKeys(Keys.CONTROL, 'v').perform();
Sample :
Load my text "test" and after with this command, paste "test"
I would like put a text in my clipboard
can I put a value directly in my ng-model, not use sendKeys ?
Yes, you can directly set the model value via .evaluate():
var elm = element(by.model("mymodel.field"));
elm.evaluate("mymodel.field = 'test';");
Putting a text into clipboard
The idea is to use an existing or dynamically create an input element where you would send the text to, select all the text in the input and copy it with a CTRL/COMMAND + C shortcut.
Sample:
var textToBeCopied = "my text";
// creating a new input element
browser.executeScript(function () {
var el = document.createElement('input');
el.setAttribute('id', 'customInput');
document.getElementsByTagName('body')[0].appendChild(el);
});
// set the input value to a desired text
var newInput = $("#customInput");
newInput.sendKeys(textToBeCopied);
// select all and copy
newInput.sendKeys(protractor.Key.chord(browser.controlKey, "a"));
newInput.sendKeys(protractor.Key.chord(browser.controlKey, "c"));
where browser.controlKey is a cross-platform way to handle CTRL/COMMAND keys:
Using cross-platform keyboard shortcuts in end-to-end testing
Somewhat related to this: I needed to test a dialog, which placed some text in the clipboard when the user pressed the 'Copy' button in the dialog. I wanted to test that the text really got copied to the clipboard. I found this 'copy-paste' library: https://www.npmjs.com/package/copy-paste . "A command line utility that allows read/write (i.e copy/paste) access to the system clipboard. It does this by wrapping pbcopy/pbpaste (for OSX), xclip (for Linux and OpenBSD), and clip (for Windows)." I would say it is a javascript module rather than a command line utility. Anyway, I started using it, as the depenency on xclip (for Linux) was not a problem for me.
Here's the snippet I use with protractor to copy text to the clipboard. I need tabs to be accepted because most of my testing involves cut-and-paste from spreadsheets, where tab is the default column delimiter.
Further, it accommodates nuances in the html body's layout better (overflow: hidden).
function copyToClipboard(browser, text) {
var id = 'someCustomIdToAvoidAliasing';
var newInput = browser.element(by.css("#" + id));
return browser.executeScript(function () {
var el = document.createElement('textarea');
el.setAttribute('id', 'someCustomIdToAvoidAliasing');
el.setAttribute('style', 'position:fixed;z-index:10000;top:0;left:0');
el.onkeydown = function(e) {
if (e.keyCode === 9) {
this.value = this.value + "\t";
return false;
}
};
document.getElementsByTagName('body')[0].appendChild(el);
})
.then(function() {
return newInput.sendKeys(text);
})
.then(function() {
return newInput.sendKeys(protractor.Key.CONTROL, "a", protractor.Key.NULL);
})
.then(function() {
return newInput.sendKeys(protractor.Key.CONTROL, "c", protractor.Key.NULL);
})
.then(function() {
return browser.executeScript(function() {
var el = document.getElementById('someCustomIdToAvoidAliasing');
el.remove();
});
});
}
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>