0

I create a button with the class name UniCopBtn, So I can copy the text in clipboard from textarea with ID transliterateTextarea. Here is JS code:

document.querySelector(".UniCopBtn").addEventListener("click", copy);

    function copy() {
        let fake = document.createElement("textarea");
        fake.value = document.querySelector("#transliterateTextarea").value;
        //fake.value = "1\n2\n3";
        document.body.appendChild(fake);
        fake.select();
        document.execCommand("copy");
        document.body.removeChild(fake);
        let notice = document.createElement("span");
        notice.className = "notice visible";
        notice.innerHTML = "Text copied to the clipboard!";
        document.body.appendChild(notice);
        setTimeout(() => {
            document.body.removeChild(notice);
        }, 3000);
    }

Now I wanted to create an another button with class ID abcd in same webpage, so I can copy the text in clipboard from the an another textarea with the ID xyz.

How can I do this?

SSKhekhaliya
  • 37
  • 1
  • 3

2 Answers2

0

Edit: The user has stated they would like one method to be used for two different text boxes/buttons. I have updated the code to reflect this. What now happens is the function that is added as an onclick handler is passed a element as a parameter. This is the element the same function should change and perform and action to.

Here you go.

The thing you need to do is select multiple elements by separating them with a , character. @john-slegers does an amazing job of explaining jQuery selectors here..

document.querySelector(".UniCopBtn").addEventListener("click",() =>  copy(document.getElementById('transliterateTextarea')));
document.querySelector(".abcd").addEventListener("click",() =>  copy(document.getElementById('xyz')));
    function copy(elementToChange) {
    alert("occuring");
        let fake = document.createElement("textarea");
        fake.value = elementToChange.value;
        //fake.value = "1\n2\n3";
        document.body.appendChild(fake);
        fake.select();
        document.execCommand("copy");
        document.body.removeChild(fake);
        let notice = document.createElement("span");
        notice.className = "notice visible";
        notice.innerHTML = elementToChange.getAttribute("id")+ "'s Text copied to the clipboard!";
        document.body.appendChild(notice);
        setTimeout(() => {
            document.body.removeChild(notice);
        }, 3000);
    }
<button class="UniCopBtn">Button UniCopBtn</button>
<button class="abcd">Button abcd</button>
<br>
<div style="color:blue">
transliterateTextarea :
<br><input type="text" id="transliterateTextarea" value="The area">
</div>
<br>
<div style="color:red">
Xyz:
<br>
<input type="text" id="xyz" value="The area">
</div>
<br>
StarshipladDev
  • 1,166
  • 4
  • 17
0

If the goal is to reuse your "copy" function, you can alter your function to take in parameters of which element you want to copy text from.

function copy(textAreaId) {
 ...
 fake.value = document.querySelector(textAreaId).value;
 ...
}

To pass in additional parameters you would need to use an anonymous function around your copy function you are passing in. EventTarget.addEventListener()

Notice that the listener is an anonymous function that encapsulates code that is then, in turn, able to send parameters to the modifyText() function, which is responsible for actually responding to the event.

document.querySelector(".UniCopBtn").addEventListener("click", () => copy('#transliterateTextarea'));

However your copy function appears to be trying to do much already. You should separate responsibilities of copying versus notifying.

Instead of using a shared "copy" function. We can use classes that are specific to "notifying" and "copying". Here is an example where we have a CopyButton class that takes in a button class, textarea id and a notifier. We attach a click handler to our copy method using attachOnClick which has to use a .bind(this) to preserve our context to use this.elementToCopyFrom and this.notifier in the copy method.

To show two different styles we are passing in "classes" and "ids" into our CopyButton class but it would be better to pass in the actual elements instead, an example of this is shown with our Notifier class where we first lookup the "#notifier" element and pass it into our Notifier. We now have clear separations of responsibilities and can extend our notifier and copy classes independently.

class Notifier {
  constructor(element, timeout) {
    this.element = element;
    this.timeout = timeout || 3000;
  }
  
  notify(message) {
    this.element.innerHTML = message;
    this.show();
    
    setTimeout(() => this.hide(), this.timeout);
  }
  
  show() {
    this.element.style.display = "block";    
  }
  
  hide() {
    this.element.style.display = "none";
  }
}

class CopyButton {
  constructor(buttonClass, elementToCopyFromId, notifier) {
    this.element = document.querySelector(buttonClass);
    this.elementToCopyFrom = document.querySelector(elementToCopyFromId);
    this.notifier = notifier;
  }
  
  attachOnClick() {
    this.element.addEventListener("click", this.copy.bind(this));
  }
  
  removeOnClick() {
    this.element.removeEventListener("click", this.copy);
  }
  
  copy() {
    this.elementToCopyFrom.select();   
    document.execCommand("copy");
    
    this.notifier.notify("text copied to clipboard!")
  }
}

const notifierElement = document.querySelector("#notifier");
const notifier = new Notifier(notifierElement);

const uniCopBtnOne = new CopyButton(
  '.UniCopBtn', 
  '#transliterateTextarea', 
  notifier,
)
uniCopBtnOne.attachOnClick();

const uniCopBtnTwo = new CopyButton(
  '.UniCopBtnTwo', 
  '#transliterateTextareaTwo', 
  notifier,
)
uniCopBtnTwo.attachOnClick();
<button class="UniCopBtn">Button 1</button>
<button class="UniCopBtnTwo">Button 2</button>
<div>
  <textarea id="transliterateTextarea">Text</textarea>
  <textarea id="transliterateTextareaTwo">Text Two</textarea>
</div>
<div id="notifier"></div>
Ace
  • 969
  • 4
  • 10