JavaScript execCommand('copy') not working

Viewed 40715

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>
8 Answers

In 2021, when compatibility with Internet Explorer is finally (almost) irrelevant, the simplest possible solution is:

function copyToClipboard(value) {
  navigator.clipboard.writeText(value)
}

Not directly related but seems like a good place to say this. When using the document.execCommand(), the element that is being used to supply the "text" must be visible on the page. So using display: none; will cause this to fail also trying to make the element height: 0; width: 0; also breaks this function. I got round this but positioning the element absolute and moving it far off the screen.

Hope this helps someone :-)

  function CopyToClipboard(element) {
      var $temp = $("<input>");
      $("body").append($temp);
      $temp.val($(element).text()).select();
      document.execCommand("copy", false, $temp.val());
      $temp.remove();
  }

ok, my approach is a little bit easier:

  1. create an extra input with type 'text'
  2. on your function call copy the value of the selected option to the extra field
  3. give extra field position absolute and left -9999 so it exists in dom but not in the visible viewport!
  4. do the rest!

here's an example:

function copyUserName() {

    //just_for_copy is my invisible extra field
    document.getElementById('just_for_copy').value = document.getElementById('user_phone').value;

    var justForCopy = document.getElementById('just_for_copy');

    justForCopy.select();

    document.execCommand("copy");
}

thanks to @Zomry I adapted your response to Typescript on Angular 9 and here is:

copyColor(colorCode: string) {
    // funcion que copia al clipboard
    const colorClicked = this.findColorObject(colorCode);
    const copyText = document.getElementById(`${colorClicked.id}`) as               HTMLInputElement;
    copyText.select();
    document.execCommand('copy');
  }
.input-color{
  /* visibility: hidden;
  height: 0px; */
  position: absolute;
  left: -9999px;
}
 <div *ngFor="let color of ColorList" class="col-4 p-0">
    <div (click)="copyColor(color.color)">
        <p>{{color.name}}</p>
        <input class="input-color" id="{{color.id}}" value="{{color.color}}" type="text" tabindex='-1' aria-hidden='true'/>
        <p>{{color.color}}</p>
      </div>
  </div>

I was trying to hidde the input but it doesn´t work until i found this solution in your CSS positioning. I hope someone find it usefull.

Related