0

I'm creating 3-4 coupon button with the text "COPY CODE", and when people click on it, it copies the coupon and change the text to "COPIED < span>some svg icon here</ span>" for 2 seconds and then change back to "COPY CODE", and will change again when clicked.

I managed to find Javascripts to copy code, but the code that changes texts are repeating, and I can't use setTimeout() to achieve the 2-second result I want.

Hope you can help me out. Here are my codes:

HTML

<p class="code" id="code10">OFF10</p>
<button onclick="copyToClipboard('#code10');changeText1()" id="button1">COPY CODE</button>

<p class="code" id="code20">OFF20</p>
<button onclick="copyToClipboard('#code20');changeText2()" id="button2">COPY CODE</button>

<p class="code" id="code35">OFF35</p>
<button onclick="copyToClipboard('#code35');changeText3()" id="button2">COPY CODE</button>

Javascript

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
function copyToClipboard(element) {
  var $temp = $("<input>");
  $("body").append($temp);
  $temp.val($(element).text()).select();
  document.execCommand("copy");
  $temp.remove();
}

function changeText1() {
  document.getElementById("button1").innerHTML = "COPIED!";
}
function changeText2() {
  document.getElementById("button2").innerHTML = "COPIED!";
}
function changeText3() {
  document.getElementById("button3").innerHTML = "COPIED!";
}

The scripts above works but they're repeating. And then I tried setTimeout() function but it's not what I expected, and I know I understood this function wrong, I'm not familiar with Javascript, just enough to understand ~10%. Here is the script I tried

function changeText1() {
  setTimeout(function() {
    document.getElementById("button1").innerHTML = "COPIED!";
  },2000)
}
Daniel MK
  • 3
  • 1
  • 2
    Your timeout is setting the text "COPIED!", what you actually want, is to reset it to "COPY" after 2 seconds. `text="COPIED!"; setTimeout(()=>{text="COPY"}, 2000)` – gXLg Sep 17 '21 at 05:47
  • Thanks for the correction! I thought setTimeout is the same as delay().hide() – Daniel MK Sep 17 '21 at 09:12

4 Answers4

0

Have found solution for your text change , Refer to this to copy text

function changeText(reed) {
  reed.innerHTML = "COPIED!";
  var reedText = reed.previousSibling;
  navigator.clipboard.writeText(reedText.textContent);
  setTimeout(function() {
    reed.innerHTML = "COPY CODE";
  }, 2000)
}
<p class="code" id="code10">OFF10</p>
<button onclick="changeText(this)" id="button1">COPY CODE</button>

<p class="code" id="code20">OFF20</p>
<button onclick="changeText(this)" id="button2">COPY CODE</button>

<p class="code" id="code35">OFF35</p>
<button onclick="changeText(this)" id="button2">COPY CODE</button>
Rana
  • 2,500
  • 2
  • 7
  • 28
0

You do not have to use separate function to change the text, as it will be a major pain when you have a lot of these buttons in your page.

Here is my solution:

HTML:-

<p class="code" id="code10">OFF10</p>
<button onclick="copyToClipboard('#code10', 'button1')" id="button1">COPY CODE</button>

<p class="code" id="code20">OFF20</p>
<button onclick="copyToClipboard('#code20', 'button2')" id="button2">COPY CODE</button>

<p class="code" id="code35">OFF35</p>
<button onclick="copyToClipboard('#code35', 'button3')" id="button3">COPY CODE</button>

Javascript:-

<script type="text/javascript">
    function copyToClipboard(element, button) {
        console.log($(element).text());
        var $temp = $("<input>");
        $("body").append($temp);
        $temp.val($(element).text()).select();
        document.execCommand("copy");
        $temp.remove();

        // waiting some time before changing the text
        setTimeout(function() {
          changeText(button);
        },2000);
    }

    function changeText(button) {
        document.getElementById(button).innerHTML = "COPIED!";
    }
</script>
Dula
  • 1,276
  • 5
  • 14
  • 23
0

Here is the final solution.. you don't onclick event in each button go as simple and clear

$(document).ready(function(){
  $('button').on('click', function(){
    var elem = $(this);
    var data_id = elem.attr('data-id');
    var $temp = $("<input>");
    $("body").append($temp);
    $temp.val(elem.prev('div').find('#'+elem.attr('data-id')).text()).select();
    document.execCommand("copy");
    $temp.remove();
    changeText(elem);
  })
})

function changeText(elem) {
  $(elem).text('copied');
  changeBack(elem);
}

function changeBack(elem) {
  setTimeout(function() {
    $(elem).text('Copy Code');
  },2000)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


<div>
<p class="code" id="code10">OFF10</p>
</div>
<button data-id="code10" type="button">COPY CODE</button>

<div>
<p class="code" id="code20">OFF20</p>
</div>
<button type="button" data-id="code20">COPY CODE</button>
<div>
<p class="code" id="code35">OFF35</p>
</div>
<button type="button" data-id="code35">COPY CODE</button>
Bhanu Pratap
  • 144
  • 6
  • I can see that in your line, you take the values for the button from the previous

    , my text is in the previous

    too but in another

    . Screenshot: https://prnt.sc/1sjh55e
    – Daniel MK Sep 17 '21 at 08:43
  • ok i update the code snippet but you have to use p tag id in the button as data-id attribute and then find the prev div and search for this id of p elem – Bhanu Pratap Sep 17 '21 at 08:58
  • Thanks, it's working on my end now! One more question about the text() method. I want to add text + for some svg icons like COPIED ....., but it seems like the text() method doesn't accept HTML tags. Is there any work around on this if you don't mind me asking? – Daniel MK Sep 17 '21 at 09:09
  • user $(elem).html('Copy Code '); instead of text() use html() and put html inside it. – Bhanu Pratap Sep 17 '21 at 09:13
0
  1. You can reduce your dependency on jQuery by using the new Clipboard API but be aware of its browser compatibility.

  2. If you move your ids to your buttons as data attributes you can reduce the repetition of your code, and also clean up your markup (removing the inline JS from the HTML).

  3. Use event delegation. Put the markup inside a container element and attach one event listener to that. Click events from the buttons will "bubble up" the DOM and that listener will catch them. Then you just need to extract the id from the button.

// Add one listener to the container element
const container = document.querySelector('#container');
container.addEventListener('click', handleClick, false);

function handleClipboard(id) {
  if (navigator.clipboard) {
    navigator.clipboard.writeText(id).then(function() {
      console.log(`${id}: code copied`);
    }, function() {
      console.log('Error');
    });
  }
}

function handleClick(e) {

  // Grab the id from the button
  const { id } = e.target.dataset;

  // Call the clipboard function with the id
  handleClipboard(id);

  // Change the text content of the button
  e.target.textContent = 'COPIED';

  // Wait two seconds, and then change it back
  setTimeout(() => e.target.textContent = 'COPY CODE', 2000);
}
<div id="container">
  <p class="code">OFF10</p>
  <button data-id="code10">COPY CODE</button>
  <p class="code">OFF20</p>
  <button data-id="code20">COPY CODE</button>
  <p class="code">OFF35</p>
  <button data-id="code35">COPY CODE</button>
</div>
Andy
  • 61,948
  • 13
  • 68
  • 95