2

I have scoured this site's similar questions, but I'm still at a loss.

Basically, I'm taking over a project for a co-worker who is moving on. His plans for an intranet page is supposed to have multiple textareas each with its own predefined text and their own "copy text" button.

On click, it copies to the user's clipboard. I pulled apart the code and for whatever reason, when I add new textareas and a button, it will not copy. The first one will.

What am I missing or doing wrong?

<html>
<head>
    <script>
    window.onload = function () {
        var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

        copyTextareaBtn.addEventListener('click', function (event) {
            var copyTextarea = document.querySelector('.js-copytextarea');
            copyTextarea.select();

            try {
                var successful = document.execCommand('copy');
                var msg = successful ? 'successful' : 'unsuccessful';
                console.log('Copying text command was ' + msg);
            } catch (err) {
                console.log('Whoops, unable to copy');
            }
        });
    }
    </script>
</head>
<body>
    <p>Test #1 </p>

    <div>
        <textarea class="js-copytextarea" readonly="readonly" style="width:20%;" 
        rows="5">Hello. This is textarea test bed #1</textarea>
        <button class="js-textareacopybtn">Copy Text (works)</button>

        <p>Test #2:</p>

        <textarea class="js-copytextarea" readonly="readonly" style="width:20%;" 
        rows="5">Hi! Welcome to textarea test bed #2 </textarea>
        <button class="js-textareacopybtn">Copy Text (broken)</button>
    </div>
</body>
</html>
MultiplyByZer0
  • 6,302
  • 3
  • 32
  • 48
BlondOverBlue
  • 25
  • 1
  • 3

5 Answers5

2

It's not working because you are only hooking the first button up to a click event because you are only getting a reference to the first button:

var copyTextareaBtn = document.querySelector('.js-textareacopybtn');

Change that to:

var copyTextareaBtn = document.querySelectorAll('.js-textareacopybtn');

.querySelector() only returns a reference to the first element it finds that matches the selector. querySelectorAll() returns a node list that contains all elements that match the selector.

Next, you'll need to attach the click event to each element within that node list and, if you convert those node lists to Arrays, the .forEach() method makes looping very easy.

See the updated code below:

window.onload = function () {
  // Get all the elements that match the selector as arrays
  var copyTextareaBtn = Array.prototype.slice.call(document.querySelectorAll('.js-textareacopybtn'));
  var copyTextarea = Array.prototype.slice.call(document.querySelectorAll('.js-copytextarea'));

  // Loop through the button array and set up event handlers for each element
  copyTextareaBtn.forEach(function(btn, idx){
  
    btn.addEventListener("click", function(){
    
      // Get the textarea who's index matches the index of the button
      copyTextarea[idx].select();

      try {
        var msg = document.execCommand('copy') ? 'successful' : 'unsuccessful';
        console.log('Copying text command was ' + msg);
      } catch (err) {
        console.log('Whoops, unable to copy');
      } 
      
    });
    
  });
}
<div>
  <p>Test #1 
    <textarea class="js-copytextarea" readonly="readonly" style="width:20%;" 
              rows="5">Hello. This is textarea test bed #1</textarea>
    <button class="js-textareacopybtn">Copy Text (works)</button>
  </p>

  <p>Test #2:
    <textarea class="js-copytextarea" readonly="readonly" style="width:20%;" 
              rows="5">Hi! Welcome to textarea test bed #2 </textarea>
    <button class="js-textareacopybtn">Copy Text (broken)</button>
  </p>
</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • 1
    Finally got it to work! Even in all my days of research, I could not find a solution for this problem. Thank you so much @Scott! – BlondOverBlue Aug 03 '17 at 00:55
0

document.querySelectorAll() select all items

<script>

window.onload = function () {

var copyTextareaBtn = document.querySelectorAll('.js-textareacopybtn');

copyTextareaBtn.forEach(function(btn){
btn.addEventListener('click', function (event) {
var copyTextarea = document.getElementById(this.dataset.txtid);
copyTextarea.select();

try {
var successful = document.execCommand('copy');
var msg = successful ? 'successful' : 'unsuccessful';
alert('Copying text command was ' + msg);
} catch (err) {
alert('Whoops, unable to copy');
}
})});

</script>

</head>

<body>
<p>Test #1 </p>

<div>
<textarea id="txta1" class="js-copytextarea" readonly="readonly" style="width:20%;" 
rows="5">Hello. This is textarea test bed #1</textarea>
<button data-txtid="txta1" class="js-textareacopybtn">Copy Text (works)</button>

<p>Test #2:</p>

<textarea id="txta2" class="js-copytextarea" readonly="readonly" style="width:20%;" 
rows="5">Hi! Welcome to textarea test bed #2 </textarea>
<button data-txtid="txta2" class="js-textareacopybtn">Copy Text</button>

</div>

  • 1
    It's generally not good practice to post an answer that is basically the same as one that was posted well before yours. Especially one that doesn't even explain itself. – Scott Marcus Aug 03 '17 at 00:49
  • Additionally, ".forEach" is not supported on node lists in all browsers. – Scott Marcus Aug 03 '17 at 02:37
0

I use this Way and it's better to understand.

1- get all values and store it in var. 2- creat text area and append it. 3 - store var value to texterea. 4- get text area value. 5- copy it :)

var form = document.getElementById('Note_form');
var title = document.getElementById('inpt_title');


// tool: Copy Note Form + Note Title .
function Copy_Note() {

    var copyTextarea = form.value+ title.value;

    var dummy = document.createElement("textarea");
    document.body.appendChild(dummy);
    dummy.value = copyTextarea;
    dummy.select();
    try {
        var msg = document.execCommand('copy') ? 'successful' : 'unsuccessful';
        console.log('Copying copyTextarea command was ' + msg);
    } catch (err) {
        console.log('Whoops, unable to copy');
    }

    document.body.removeChild(dummy);










}
                <!-- title -->
                <input type="text" id="inpt_title"  class="copy_erea" placeholder="The title.." maxlength="70" autofocus>
           
       
                <!-- the note -->
                <textarea id="Note_form" class="copy_erea" placeholder="The Content.." oninput="note_Edite(this.value);"></textarea>
          
                  <button id="copy_btn" onclick="Copy_Note();">copy</button>
Omar bakhsh
  • 896
  • 11
  • 18
0

Same here. i was searching for two days for this answer and this answer worked for me found on another thread here.

https://stackoverflow.com/a/51261023/2347501

 <script>
    function CopyToClipboard(containerid) {
        if (window.getSelection) {
            if (window.getSelection().empty) { // Chrome
                window.getSelection().empty();
            } else if (window.getSelection().removeAllRanges) { // Firefox
                window.getSelection().removeAllRanges();
            }
        } else if (document.selection) { // IE?
            document.selection.empty();
        }
    
        if (document.selection) {
            var range = document.body.createTextRange();
            range.moveToElementText(document.getElementById(containerid));
            range.select().createTextRange();
            document.execCommand("copy");
        } else if (window.getSelection) {
            var range = document.createRange();
            range.selectNode(document.getElementById(containerid));
            window.getSelection().addRange(range);
            document.execCommand("copy");
        }
    }</script>


      <button id="button1" onclick="CopyToClipboard('div1')">Click to copy</button>
    <div id="div1">Text To Copy </div>
jaxweb
  • 19
  • 3
0

This is old code, just a little JavaScript modification, hope it helps.

<form name="copy">
<textarea cols="40" name="txt" readonly rows="10">

Text 1
Bla Bla Bla

</textarea><br>
<input type='button' value='Copy all code' onclick="javascript:this.form.txt.focus();this.form.txt.select();document.execCommand('copy');"/></form>

<form name="copy">
<textarea cols="40" name="txt" readonly rows="10">

Text 2
Bla Bla Bla

</textarea><br>
<input type='button' value='Copy all code' onclick="javascript:this.form.txt.focus();this.form.txt.select();document.execCommand('copy');"/></form>

<form name="copy">
<textarea cols="40" name="txt" readonly rows="10">

Text 3
Bla Bla Bla

</textarea><br>
<input type='button' value='Copy all code' onclick="javascript:this.form.txt.focus();this.form.txt.select();document.execCommand('copy');"/></form>

However the input type of this code must be between the </textarea> and </form> syntax.

<input type='button' value='Copy all code' onclick="javascript:this.form.txt.focus();this.form.txt.select();document.execCommand('copy');"/>
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 06 '23 at 10:37