How to make my copy text JS listen to more than one button?

Viewed 162

How do I make the JS to work for multiple copy buttons? For example, think like 5 posts in a page feed, each with their own copy button. For now it only seems to work for the first button in the page, and other buttons do nothing.

HTML/PHP:

<input type="text" value="<?php the_permalink();?>" id="myInput">

<div class="copytooltip">
<button onclick="myFunction()" onmouseout="outFunc()">
  <span class="copytooltiptext" id="myCopyTooltip">Copy to clipboard</span>
  Copy text
  </button>
</div>

JS:

function myFunction() {
  var copyText = document.getElementById("myInput");
  copyText.select();
  copyText.setSelectionRange(0, 99999);
  document.execCommand("copy");
  
  var tooltip = document.getElementById("myCopyTooltip");
  tooltip.innerHTML = "Copied: " + copyText.value;
}

function outFunc() {
  var tooltip = document.getElementById("myCopyTooltip");
  tooltip.innerHTML = "Copy to clipboard";
}
3 Answers

Using dynamic IDs is the way to go but there is another, a little bit more complex option. It involves using event objects. You should put your input field along with the button under the same parent element. Then you can traverse DOM based on the event's target element, find common parent for your button and input field and then find the input field in the child Nodes of the common parent. Something along these lines:

function myFunction(event) {
  const commonParent = event.currentTarget.parentElement;
  let inputElement = null;
  for (node of commonParent.childNodes) {
    if(node instanceof HTMLInputElement) {
        inputElement = node;
      break;
    } 
  }
 
  inputElement.select();
  inputElement.setSelectionRange(0, 99999);
  document.execCommand("copy");
  
  event.currentTarget.innerText = `Copied: ${inputElement.value}`;
}

function outFunc(event) {
    event.currentTarget.innerText = "Copy to clipboard";
}
<div class="post-wrapper">
  <input type="text" value="Value 1" id="myInput">
  <br>
  <button onclick="myFunction(event)" onmouseout="outFunc(event)">
    Copy to clipboard
  </button>
</div>

<div class="post-wrapper">
  <input type="text" value="Value 2" id="myInput">
  <br>
  <button onclick="myFunction(event)" onmouseout="outFunc(event)">
    Copy to clipboard
  </button>
</div>

If you have multiple buttons, you may use different IDs and pass to the JS

For example, if you have two buttons, then :

<input type="text" value="OK 1" id="myInput(1)">

<div class="copytooltip">
<button onclick="myFunction(1)" onmouseout="outFunc(1)">
  <span class="copytooltiptext" id="myCopyTooltip(1)">Copy to clipboard</span>
  Copy text
  </button>
</div>


<input type="text" value="OK 2" id="myInput(2)">

<div class="copytooltip">
<button onclick="myFunction(2)" onmouseout="outFunc(2)">
  <span class="copytooltiptext" id="myCopyTooltip(2)">Copy to clipboard</span>
  Copy text
  </button>
</div>

<script>
function myFunction(var1) {
  var copyText = document.getElementById("myInput(" + var1 + ")");
  copyText.select();
  copyText.setSelectionRange(0, 99999);
  document.execCommand("copy");
  
  var tooltip = document.getElementById("myCopyTooltip(" + var1 + ")");
  tooltip.innerHTML = "Copied: " + copyText.value;
}

function outFunc(var1) {
  var tooltip = document.getElementById("myCopyTooltip(" + var1+  ")");
  tooltip.innerHTML = "Copy to clipboard";
}

</script>

you need to use addEventListener() for multiple copy buttons

<button class="btn">
  <span class="copytooltiptext" id="myCopyTooltip">Copy to clipboard</span>
  Copy text
</button>
document.querySelector('.btn').addEventListener('mouseout', function(e) {
      outFunc()
})

document.querySelector('.btn').addEventListener('click', function(e) {
      myFunction()
})
Related