'Button var to clipboard

In the funtion below there is this var link. By clicking on the button I want to copy the var to clipboard.

function displayUser(user) {
    
var text = `Account No.: ${user.userId} <br> Country: ${user.country} <br> 
 "<button onclick="copyToClipboard(link)"> Copy Link</button>"`;
var link = `${user.Url}`;

grid.innerHTML += text;
}

function user(data) {
    data.result.roomList.forEach((user) => displayUser(user));
}

What I found here and tried is this funktion:

function copyToClipboard(link){
    var dummy = document.createElement("input");
    dummy.style.display = 'none';
    document.body.appendChild(dummy);
    dummy.setAttribute("id", "dummy_id");
    document.getElementById("dummy_id").value=link;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);

By clicking on the button it says "link is not defined". Anyone know how to make this work?

Thanks in advance



Solution 1:[1]

You could do it like this. This didn't make the copying to clipboard work, but that's how you can pass it to the function like you want it.

function displayUser(user) {
    
    var grid = document.getElementById("testgrid");
    console.log(grid);

    var link = `${user.Url}`;
    var text = `Account No.: ${user.userId} <br> Country: ${user.country} <br> 
     <button onclick="copyToClipboard('${link}')"> Copy Link</button>`;
    
    grid.innerHTML += text;
}
    
function user(data) {
    data.result.roomList.forEach((user) => displayUser(user));
}

function copyToClipboard(link){
    console.log(link);
    var dummy = document.createElement("input");
    dummy.style.display = 'none';
    document.body.appendChild(dummy);
    dummy.setAttribute("id", "dummy_id");
    document.getElementById("dummy_id").value=link;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}

displayUser({Url: "bla", country: "blabla"});

Solution 2:[2]

I tried the version of Cypherjac looking like this now. I don't get an error anymore but also no result in the clipboard.

function displayUser(user) {

var link = user.Url;
var text = `Account No.: ${user.userId} <br> Country: ${user.country} <br> 
<button onclick="copyToClipboard(${link})"> Copy Link</button>`;

grid.innerHTML += text;
}

function user(data) {
  data.result.roomList.forEach((user) => displayUser(user));
}

function copyToClipboard(link){
    var dummy = document.createElement("input");
    dummy.style.display = 'none';
    document.body.appendChild(dummy);
    dummy.setAttribute("id", "dummy_id");
    document.getElementById("dummy_id").value=link;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
} 

Then I tried the suggestions of Chris G looking like this now. But also no error and no result. Any more ideas?

let link;               
            
function displayUser(user) {
    
var text = `Account No.: ${user.userId} <br> Country: ${user.country} <br> 
 "<button onclick="copyToClipboard()"> Copy Link</button>"`;
link = user.Url;

grid.innerHTML += text;
}

function user(data) {
    data.result.roomList.forEach((user) => displayUser(user));
}

function copyToClipboard(){
    var dummy = document.createElement("input");
    dummy.style.display = 'none';
    document.body.appendChild(dummy);
    dummy.setAttribute("id", "dummy_id");
    document.getElementById("dummy_id").value=link;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}

Solution 3:[3]

If you're looking for another alternative, I will provide one that I've used before and it works.

So the function has a fallback for other browsers as well, so it has support for Edge, Chrome and Firefox ... IE maybe and maybe not

On the click of a button with the style provided when initializing the function: new clipboardHandler('copy-exec'), it triggers a document copy function to select the element which is the previousSibling of the element

You can of course tweak it to your needs.

Then also NOTE: The 2 elements are placed back to back in the HTML. That's because if you put any space between them, the previousSibling of the element becomes that element, which is basically a non-breaking space character

But once you change the target element: previousSibling, it will work according to your needs

function clipboardHandler(c){
  function copy_relative_text(node){
    if(document.body.createTextRange){
      const range = document.body.createTextRange();
      range.moveToElementText(node);
      range.select();
      document.execCommand('copy');
    }
    else if(window.getSelection){
      const selection = window.getSelection();
      const range = document.createRange();
      range.selectNodeContents(node);
      selection.removeAllRanges();
      selection.addRange(range);
      document.execCommand('copy');
    }
    else {
      console.warn("Could not select text in node");
    }
  }
  function clear_selection(){
    if(window.getSelection){
      window.getSelection().removeAllRanges();
    }
    else if(document.selection){
      document.selection.empty();
    }
  }
  this.clipboard_target = function(){
    var clips = document.getElementsByClassName(c);
    for(var i = 0; i < clips.length; i++){
      clips[i].onclick = function(){
        copy_relative_text(this.previousSibling);
        setTimeout(() => {
          clear_selection();
        }, 500);
        this.innerHTML = 'Copied';
        setTimeout(() => {
          this.innerHTML = 'Copy Link';
        }, 2000);
      };
    }
    return this;
  };
}

let clip = new clipboardHandler('copy-exec')
clip.clipboard_target()
.copy-text {
  margin-bottom: 3px;
}
.copy-exec {
  background-color: teal;
  color: #FFF;
  border-radius: 5px;
  padding: 5px;
  border-style: none;
  margin: 2px;
}
<p class="copy-text">I will be copied to your clipboard!!!</p><button class="copy-exec">Copy Link</button>

Solution 4:[4]

This section here should be:

function displayUser(user) {
    
    var link = user.Url;
    var text = `Account No.: ${user.userId} <br> Country: ${user.country} <br> 
    "<button onclick="copyToClipboard('${link}')"> Copy Link</button>"`;

    grid.innerHTML += text;
}

function user(data) {
    data.result.roomList.forEach((user) => displayUser(user));
}

The variable link was not accessible, because you defined it after, and also you did not enclose it correctly


I've changed this section:

... onclick="copyToClipboard('${link}')" ...

Because when the function is called, it is called with the actual value as the parameter, so when enclosed in quotes it will act as a string

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Arwez
Solution 2 Steve
Solution 3 Cypherjac
Solution 4