earmsby's avatar
Level 6

button/link to copy text to clipboard

I have a livewire component & blade which is used within a Filament 4.x application. The component retrieves some data about a Model called Publication and displays it to the user like this:

This information needs to be copied to a sheet outside the Filament app, so I'd love to have a button or link that when clicked would copy the six values (just the values separated by a comma) to the clipboard so they could more easily pasted in. This seems like it should be do-able but I'm not sure where to start on it. Any ideas?

0 likes
2 replies
LaryAI's avatar
Level 58

Certainly! You can achieve this easily by using a button with a small bit of Alpine.js (which comes with Filament out-of-the-box) and a hidden input or a computed string of the values you want to copy.

Here's a step-by-step solution:


1. Add an Alpine.js Data Block and Button

You'll construct the string from your variables and then use JavaScript to copy it to the clipboard.

Example Blade Snippet:

<div 
    x-data="{
        get values() {
            return [
                '{{ $fiveYearSales }}',
                '{{ $allTimeSales }}',
                '{{ $pageCount }}',
                '{{ $isDigitized }}',
                '{{ $lastPrintedBy }}',
                '{{ $monthSupply }}',
            ].join(',');
        },
        copy() {
            navigator.clipboard.writeText(this.values)
                .then(() => { $dispatch('notify', { type: 'success', message: 'Copied to clipboard!' }); })
                .catch(() => { $dispatch('notify', { type: 'danger', message: 'Copy failed!' }); });
        }
    }"
>
    <!-- ... your blade form ... -->

    <button 
        type="button"
        class="mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
        x-on:click="copy"
    >
        Copy Info to Clipboard
    </button>
</div>

2. Explanation

  • The values getter concatenates your six variables, comma-separated.
  • The copy() function calls the Clipboard API to copy the string.
  • Optional: Use $dispatch('notify', ...) to let Filament's notification system alert the user.

3. Alternative Without Notifications

If you don't care about user feedback, simplify copy() to:

copy() { navigator.clipboard.writeText(this.values); }

4. No Alpine? Vanilla JS Fallback

Add a hidden input with the values, then attach a click handler to the button:

<input type="text" id="toCopy" value="{{ $fiveYearSales }},{{ $allTimeSales }},{{ $pageCount }},{{ $isDigitized }},{{ $lastPrintedBy }},{{ $monthSupply }}" style="position: absolute; left: -9999px;" readonly>
<button type="button" onclick="
    let copyText = document.getElementById('toCopy');
    copyText.select();
    document.execCommand('copy');
    alert('Copied!');
">Copy Info to Clipboard</button>

5. Final Notes

  • Recommended: Use the Alpine.js/Clipboard API approach for a modern, user-friendly experience in Filament.
  • Adapt the variable names as needed.
  • Works seamlessly inside your existing Blade template.

Let me know if you need a Livewire-based approach as well, but for user-triggered clipboard copying, Alpine/JS is ideal!

earmsby's avatar

I'd like to use the Alpine apprioach given, but when I implement it, I'm getting the error below in the JS console:

Alpine Expression Error: Cannot read properties of undefined (reading 'writeText')

Expression: "copy"

 <button type=​"button" class=​"mt-4 px-4 py-2 bg-blue-600 text-white rounded hover:​bg-blue-700" x-on:click=​"copy">​ Copy Info to Clipboard ​</button>​
normalErrorHandler @ livewire.js?id=0f6341c0:1133
handleError @ livewire.js?id=0f6341c0:1125
tryCatch @ livewire.js?id=0f6341c0:1121
(anonymous) @ livewire.js?id=0f6341c0:3933
handler4 @ livewire.js?id=0f6341c0:3235
(anonymous) @ livewire.js?id=0f6341c0:3299
(anonymous) @ livewire.js?id=0f6341c0:3237

I played around a little with logging a few values to the console in the copy() function like:

        console.log('Hello!');
        console.log({{ $fiveYearSales}});

The console showed Hello! but not the value of $fiveYearSales. I'm wondering if the values are not available because they are retrieved by livewire after a value is entered in the form?

Please or to participate in this conversation.