88

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
harman
  • 1,435
  • 1
  • 12
  • 13
  • I doubt you can copy a raw JS object to the clipboard. `.execCommand('copy')` copies a selection on a page (if allowed in user preferences). You could try to stringify the array, then populate a textarea with it, select all from textarea, and then copy with `execCommand`. When pasting, capture the event, and parse the content back to array. – Teemu Nov 22 '15 at 14:17
  • OK.. Thanks for pointing me to a direction. I thought that this was probably not possible as it did not seem to return any direct search results. So I guess I will try to do as you suggested. – harman Nov 22 '15 at 14:33
  • This is maybe a stupid question, but where/how would you paste a raw JS object? – Teemu Nov 22 '15 at 14:44
  • Well, basically this is for a wordpress thingy.. I am just collecting all elements whose ID = some id to then paste the comma separated IDs in wordpress conditional tags. Hope that makes sense.. – harman Nov 22 '15 at 16:27
  • Correction for the sake of making sense... I am collecting all elements who have been checkboxed and NOT whose ID = some ID... ;-) – harman Nov 22 '15 at 16:38

10 Answers10

128
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')
random_user_name
  • 23,924
  • 7
  • 69
  • 103
walkman
  • 1,433
  • 2
  • 7
  • 7
43

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>
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
harman
  • 1,435
  • 1
  • 12
  • 13
  • 9
    Could this be done without creating an HTML element? Say for example I just wanted to copy a string to a users clipboard when they click a button or pre-specified element? – VikingGoat Dec 28 '16 at 19:00
  • 6
    I'd recommend using a "textarea" instead of an "input", that way you can copy line breaks as well. – Telmo Trooper Dec 19 '17 at 17:50
22

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.

Peter Paulovics
  • 221
  • 2
  • 4
  • 1
    Be careful if you use texarea. setAttribute('value', value), which works with "input" does not work with "textarea". – Eduard May 05 '18 at 10:18
16

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);
}
lbrutti
  • 1,073
  • 14
  • 16
  • 5
    change $(dummy).css('display','none'); into dummy.style.display = 'none'; to avoid jQuery – Kardi Teknomo Apr 26 '19 at 09:28
  • 4
    Chrome needs to have dummy displayed. So I removed one line of the code and it works, thanks – shukshin.ivan Aug 01 '19 at 15:40
  • 1
    @shukshin.ivan thanks for that input! I did end up changing that line to this: `dummy.setAttribute("hidden", true);` true could be anything since the html syntax for the hidden attribute doesn't have any value. – Jimmy Westberg Aug 21 '19 at 07:14
  • I also made a simple check if the "value" sent is an object, if so stringify: `if (typeof stuffToAddToClipboard === "object") { stuffToAddToClipboard = JSON.stringify(stuffToAddToClipboard); }` – Jimmy Westberg Aug 21 '19 at 07:21
  • Hello,can someone explain downvoting? I can't see any clear resons in my answer... – lbrutti Aug 27 '20 at 14:04
  • I am not one of the downvoters but your code is using a command `document.execCommand()` that is [obsolete and could be removed any time](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) – Lelio Faieta Sep 04 '20 at 13:40
  • Thanks for pointing this out @LelioFaieta, I didn't check this kind of issues and grant for good other given answer ;) – lbrutti Sep 04 '20 at 15:27
  • what's reason for setting the id on the dummy element and then using getElementById to set the value? It seems like extra work for nothing, you already have a reference to the element - you used it to set the id. Why? – Levesque Feb 12 '21 at 18:28
  • Levesque, you right. I haven't been checking this chunk in years...Honsestly i can't tell if i wrote it like this for some reason (maybe some hack on the project i was on then...). – lbrutti Feb 13 '21 at 17:37
8

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

Evgeny
  • 5,247
  • 3
  • 49
  • 58
6

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>
Pedro Lobito
  • 75,541
  • 25
  • 200
  • 222
  • 1
    It worked for me, but only without "hidden" attribute for the input. In Chromium it forces a style "display: none !important" that is not overwritten by manually setting "display: block" on row 4 of your script. – II ARROWS Apr 28 '20 at 15:02
  • Oddly, this continues to fail for me. Instead, when I try pasting, it just pastes the old text in the clipboard. Is this a known issue? – Destaq Aug 12 '20 at 17:29
4

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.

sr9yar
  • 3,453
  • 1
  • 38
  • 51
2

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.

Pierre Henry
  • 14,204
  • 16
  • 75
  • 92
1

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>
anothernode
  • 4,369
  • 11
  • 37
  • 53
Richard Ramos
  • 41
  • 1
  • 7
0

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>