Search code examples
javascriptjquerycopyclipboard

Copy to clipboard in javascript doesn't work properly


I have the following code:

$(document).ready(function () {
            var usernames = ["user1", "user2", "user3", "user4", "user5", "user6", "user7"];
            var ids = ["76561199144601203", "76561199085110484", "76561199202629307", "76561198977492126", "76561199107090117", "76561199156985347", "76561199195037086"];
            var part = '';
            for (var i = 0; i < usernames.length; i++) {
                $('#user_id_table > tbody:last-child').append('<tr><th scope="row">' + usernames[i] + '</th><td><button onclick="CopyIdToClipboard(' + ids[i] + ')">' + ids[i] + '</button></td></tr>');
            }
        });

        function CopyIdToClipboard(text) {
            // Create a temporary input element
            var $tempInput = $('<input type="text">');
            $('body').append($tempInput);

            // Set the value of the temporary input element to the text
            $tempInput.val(text).select();

            // Copy the text to the clipboard
            document.execCommand('copy');

            // Remove the temporary input element
            $tempInput.remove();

            alert("Copied the text: " + text);
        } 
<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>

<body>
    <!-- Jquery -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <div class="container">
        <div class="row">
            <table class="table border" id="user_id_table">
                <thead>
                    <tr>
                        <th scope="col">USERNAME</th>
                        <th scope="col">ID</th>
                    </tr>
                </thead>
                <tbody>
                </tbody>
            </table>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
        crossorigin="anonymous"></script>
</body>

</html>

My problem is when I press the button to copy to clipboard, in the alert and in my clipboard there is a round up of the ID even if it is a string, the first two numbers change. Example: The first one(76561199144601203) gives me this "76561199144601200"

It shouldn't change anything, it should only get copied to the clipboard. I tried other approches like navigator.clipboard.writeText() but the result is the same.

What I'm doing wrong? Anyone can help?


Solution

  • With some slight rework of the CopyIdToClipboard function to use the button element to get the text, try the runnable example below.

    Basically the changes are all in the javascript handling:

    1. In the loop where the buttons are added, the onclick event changes to: onclick="CopyIdToClipboard(this)" ... (this is a reference to the button element itself)
    2. The parameter to CopyIdToClipboard changes from text to element (as it is now an element reference, and not text)
    3. To the val(), the button element's textContent is set as the value. (the button's text)

    $(document).ready(function () {
                var usernames = ["user1", "user2", "user3", "user4", "user5", "user6", "user7"];
                var ids = ["76561199144601203", "76561199085110484", "76561199202629307", "76561198977492126", "76561199107090117", "76561199156985347", "76561199195037086"];
                var part = '';
                for (var i = 0; i < usernames.length; i++) {
                    $('#user_id_table > tbody:last-child').append('<tr><th scope="row">' + usernames[i] + '</th><td><button onclick="CopyIdToClipboard(this)">' + ids[i] + '</button></td></tr>');
                }
            });
    
            function CopyIdToClipboard(element) {
                // Create a temporary input element
                var $tempInput = $('<input type="text">');
                $('body').append($tempInput);
    
                // Set the value of the temporary input element to the text
                $tempInput.val(element.textContent).select();
                         // note that .innerHTML works too
    
                // Copy the text to the clipboard
                document.execCommand('copy');
    
                // Remove the temporary input element
                $tempInput.remove();
    
                alert("Copied the text: " + element.innerHTML);
            } 
    <!doctype html>
    <html lang="en">
    
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Bootstrap demo</title>
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
            integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
    </head>
    
    <body>
        <!-- Jquery -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
        <div class="container">
            <div class="row">
                <table class="table border" id="user_id_table">
                    <thead>
                        <tr>
                            <th scope="col">USERNAME</th>
                            <th scope="col">ID</th>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>
            </div>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
            crossorigin="anonymous"></script>
    </body>
    
    </html>