# \[IGN-5196\]Perspective - Copy to clipboard button

**URL:** <https://forum.inductiveautomation.com/t/ign-5196-perspective-copy-to-clipboard-button/53285>\
**Category:** Ignition\
**Tags:** scripting, perspective, ignition81\
**Created:** [November 19, 2021, 12:21pm UTC](https://forum.inductiveautomation.com/t/ign-5196-perspective-copy-to-clipboard-button/53285 "2021-11-19T12:21:05Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![jakned](https://avatars.discourse-cdn.com/v4/letter/j/4da419/32.png) [@jakned](https://forum.inductiveautomation.com/u/jakned)\
**Post date:** [November 19, 2021, 12:21pm UTC](https://forum.inductiveautomation.com/t/ign-5196-perspective-copy-to-clipboard-button/53285/1 "2021-11-19T12:21:05Z")

</div>

Hi,  
is it possible to create this functionality in Perspective (without developing custom component)?

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/7/b7b78ab4081f985258580659bc43cc8c45bec348.png)

Thanks

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [November 19, 2021, 4:12pm UTC](https://forum.inductiveautomation.com/t/ign-5196-perspective-copy-to-clipboard-button/53285/2 "2021-11-19T16:12:23Z")

</div>

No, we don’t expose the clipboard API. The modern clipboard API also only works in HTTPS contexts, so it may or may not ever land in Perspective first-party.

---

<div class="post-metadata">

**Author:** ![justin.huggins](https://avatars.discourse-cdn.com/v4/letter/j/d07c76/32.png) [@justin.huggins](https://forum.inductiveautomation.com/u/justin.huggins)\
**Post date:** [September 18, 2024, 7:03pm UTC](https://forum.inductiveautomation.com/t/ign-5196-perspective-copy-to-clipboard-button/53285/3 "2024-09-18T19:03:05Z")

</div>

I am looking to do something similar with a table. This was 3 years ago. Not sure if any new updates have been provided? Basically, I want a user to be able to click a button to capture all the data from within a table to paste in a email or text file.

---

<div class="post-metadata">

**Author:** ![justin.huggins](https://avatars.discourse-cdn.com/v4/letter/j/d07c76/32.png) [@justin.huggins](https://forum.inductiveautomation.com/u/justin.huggins)\
**Post date:** [September 18, 2024, 7:06pm UTC](https://forum.inductiveautomation.com/t/ign-5196-perspective-copy-to-clipboard-button/53285/4 "2024-09-18T19:06:35Z")

</div>

I suppose exporting to a text or CSV file might work also. Not as ideal as clipboard.

---

<div class="post-metadata">

**Author:** ![Paul.M](https://avatars.discourse-cdn.com/v4/letter/p/c0e974/32.png) [@Paul.M](https://forum.inductiveautomation.com/u/Paul.M)\
**Post date:** [May 15, 2026, 9:24am UTC](https://forum.inductiveautomation.com/t/ign-5196-perspective-copy-to-clipboard-button/53285/5 "2026-05-15T09:24:50Z")

</div>

Hello,

Don't know if this is still in need, but I had the same request, I was able to build in Web Dev

Web Dev

```python

    defaultText = ""

    params = request.get("params", {})

    textToCopy = params.get("text", defaultText)

    if textToCopy == "" and len(params.keys()) > 0:
        firstKey = list(params.keys())[0]
        if firstKey != "text":
            textToCopy = firstKey

    if isinstance(textToCopy, list):
        textToCopy = textToCopy[0] if len(textToCopy) > 0 else defaultText

    textToCopy = str(textToCopy)

    def js_escape(value):
        return value.replace("\\", "\\\\").replace("'", "\\'").replace("\n", "\\n").replace("\r", "")

    jsText = js_escape(textToCopy)

    html = """
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <style>
        html, body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            background: transparent;
            overflow: hidden;
            font-family: Segoe UI, Arial, sans-serif;
        }

        .wrapper {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: flex-start;
            gap: 6px;
        }

        .copy-button {
            width: 24px;
            height: 24px;
            min-width: 24px;
            border: none;
            background: transparent;
            color: #163B77;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 0;
            margin: 0;
            outline: none;
            box-shadow: none;
        }

        .copy-button:hover {
            color: #0078D4;
        }

        .copy-button:active {
            transform: scale(0.92);
        }

        .copy-button.copied {
            color: #107C10;
        }

        .copy-button.error {
            color: #B42318;
        }

        svg {
            width: 20px;
            height: 20px;
            fill: currentColor;
            display: block;
        }

        .copy-message {
            font-size: 12px;
            font-weight: 600;
            color: #107C10;
            white-space: nowrap;
            opacity: 0;
            transform: translateX(-4px);
            transition: opacity 0.16s ease, transform 0.16s ease;
            pointer-events: none;
        }

        .copy-message.show {
            opacity: 1;
            transform: translateX(0);
        }

        .copy-message.error {
            color: #B42318;
        }
    </style>
</head>

<body>
    <div class="wrapper">
        <button class="copy-button" id="copyButton" title="Copiaza grupul" onclick="copyToClipboard()">
            <svg viewBox="0 0 24 24" aria-hidden="true">
                <path d="M16 1H4C2.9 1 2 1.9 2 3v14h2V3h12V1zm3 4H8C6.9 5 6 5.9 6 7v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"></path>
            </svg>
        </button>

        <span class="copy-message" id="copyMessage">Grup copiat!</span>
    </div>

    <script>
        const textToCopy = ' __TEXT_TO_COPY__';

        async function copyToClipboard() {
            const button = document.getElementById('copyButton');
            const message = document.getElementById('copyMessage');

            try {
                await navigator.clipboard.writeText(textToCopy);

                button.classList.remove('error');
                button.classList.add('copied');

                message.innerText = 'Grup copiat!';
                message.classList.remove('error');
                message.classList.add('show');

                setTimeout(function() {
                    button.classList.remove('copied');
                    message.classList.remove('show');
                }, 1600);

            } catch (error) {
                button.classList.remove('copied');
                button.classList.add('error');

                message.innerText = 'Nu s-a copiat';
                message.classList.add('error');
                message.classList.add('show');

                setTimeout(function() {
                    button.classList.remove('error');
                    message.classList.remove('show');
                    message.classList.remove('error');
                }, 1800);
            }
        }
    </script>
</body>
</html>
"""

    html = html.replace(" __TEXT_TO_COPY__", jsText)

    return {
        "html": html
    }

```

On my perspective page I have a IFrame component with this src

> "/system/webdev/ProjectName/webdevResourceName?text=textToBeCoppied"

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/1/0/10145a86bb4f1baf2751b23631d2778ed53ec32c.png)

When I click on the right icon text from the left label it's copied on the client browser

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/9/b950ee634da271ed1edd40be65cdee26bd97192b.png)

Unfortunately this method works only with text and require web dev module
