JavaScript execCommand('copy') not working

Rajesh k picture Rajesh k · Jul 15, 2017 · Viewed 32.7k times · Source

I am unable to use the execCommand('copy'), trying to copy value which is selected in multi-select option. iam getting value in "temp" but the value which is getting in temp not copying or getting in clipboard.

{
        $propArr=array_unique($properties);
        echo "<div class='table-responsive'>";
            echo "<table class='bordered'>";
            foreach($propArr as $keyProp =>$val){
                echo "<tr>";
                    echo "<td>$val</td><td>";
                    echo "<select name='propval' id='propval' onclick='showpropval(this.value);' class='form-control' multiple>";
                    foreach($values as $k => $v){
                        if($val==$k){
                            foreach($v as $kv =>$fval){
                                echo "<option value='$fval'>$fval</option>";
                            }
                        }
                    }
                    echo "</select>";
                    echo"</td>";
                echo "</tr>";
            }
            echo "</table>";
        echo "</div>";
        }

<script>
        function showpropval(val)
        {
            var temp = val;
            temp.execCommand("copy");

        }
    </script>

Answer

Zomry picture Zomry · Jul 15, 2017

I understand that your intention is the following: you want to copy the values of the selected options to the clipboard as soon as you select it.

When you use document.execCommand('copy'), you copy whatever is selected on the page (such as content in a paragraph or in an input field itself).

The catch is however that selecting options in <select> is not considered to be selected text. Worse yet, if you would like to trigger selecting text via javascript, there are some restrictions: you can only call .select() on an <input>or a <textarea> element.

Here is what I would do: copy the selected options to a separate (not visible) input-field, select it and copy the content from that.

Here is a fiddle that can serve as a demo: https://jsfiddle.net/Zomry/metcfvcq/13/

I wil break it down here:

First, add this element to the page. This is the input-field where we will copy the content from to the clipboard. Note that I have added tabindex -1 so you cannot reach it via tab key. I also included aria-hidden so screenreaders know it should ignore this.

<input class='copyfrom' tabindex='-1' aria-hidden='true'>

Then make the input field invisible by putting it off screen (did not work if I tried display: none; or other tricks)

<style>
    .copyfrom {
        position: absolute;
        left: -9999px;
    }
</style>

Then copy the value to the input field, select it and copy it.

var input = document.querySelector("input.copyfrom"); // select the input field

function showpropval(val) {
    var selectedValues = getSelectValues(this); // get selected values
    input.value = test.join(','); // join them in a comma separated list
    input.select(); // select offscreen inputs text
    document.execCommand("copy"); // copy it
    this.focus(); // focus back on original, so we don't see any glitches
} 

// credits to: https://stackoverflow.com/questions/5866169/how-to-get-all-selected-values-of-a-multiple-select-box
function getSelectValues(select) {
    var result = [];
    var options = select && select.options;
    var opt;

    for (var i=0, iLen=options.length; i<iLen; i++) {
        opt = options[i];

        if (opt.selected) {
          result.push(opt.value || opt.text);
        }
    }
  return result;
}